在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:json-path/JsonPath开源软件地址:https://github.com/json-path/JsonPath开源编程语言:Java 97.1%开源软件介绍:Jayway JsonPathA Java DSL for reading JSON documents. Jayway JsonPath is a Java port of Stefan Goessner JsonPath implementation. News30 Jan 2022 - Released JsonPath 2.7.0 02 Jun 2021 - Released JsonPath 2.6.0 10 Dec 2020 - Released JsonPath 2.5.0 05 Jul 2017 - Released JsonPath 2.4.0 26 Jun 2017 - Released JsonPath 2.3.0 29 Feb 2016 - Released JsonPath 2.2.0 22 Nov 2015 - Released JsonPath 2.1.0 19 Mar 2015 - Released JsonPath 2.0.0 11 Nov 2014 - Released JsonPath 1.2.0 01 Oct 2014 - Released JsonPath 1.1.0 26 Sep 2014 - Released JsonPath 1.0.0 Getting StartedJsonPath is available at the Central Maven Repository. Maven users add this to your POM. <dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.7.0</version>
</dependency> If you need help ask questions at Stack Overflow. Tag the question 'jsonpath' and 'java'. JsonPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination
with an XML document. The "root member object" in JsonPath is always referred to as JsonPath expressions can use the dot–notation
or the bracket–notation
Operators
FunctionsFunctions can be invoked at the tail end of a path - the input to a function is the output of the path expression. The function output is dictated by the function itself.
Filter OperatorsFilters are logical expressions used to filter arrays. A typical filter would be
Path ExamplesGiven the json {
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
Reading a DocumentThe simplest most straight forward way to use JsonPath is via the static read API. String json = "...";
List<String> authors = JsonPath.read(json, "$.store.book[*].author"); If you only want to read once this is OK. In case you need to read an other path as well this is not the way to go since the document will be parsed every time you call JsonPath.read(...). To avoid the problem you can parse the json first. String json = "...";
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
String author0 = JsonPath.read(document, "$.store.book[0].author");
String author1 = JsonPath.read(document, "$.store.book[1].author"); JsonPath also provides a fluent API. This is also the most flexible one. String json = "...";
ReadContext ctx = JsonPath.parse(json);
List<String> authorsOfBooksWithISBN = ctx.read("$.store.book[?(@.isbn)].author");
List<Map<String, Object>> expensiveBooks = JsonPath
.using(configuration)
.parse(json)
.read("$.store.book[?(@.price > 10)]", List.class); What is Returned When?When using JsonPath in java its important to know what type you expect in your result. JsonPath will automatically try to cast the result to the type expected by the invoker. //Will throw an java.lang.ClassCastException
List<String> list = JsonPath.parse(json).read("$.store.book[0].author")
//Works fine
String author = JsonPath.parse(json).read("$.store.book[0].author") When evaluating a path you need to understand the concept of when a path is
By default a simple object mapper is provided by the MappingProvider SPI. This allows you to specify the return type you want and the MappingProvider will
try to perform the mapping. In the example below mapping between String json = "{\"date_as_long\" : 1411455611975}";
Date date = JsonPath.parse(json).read("$['date_as_long']", Date.class); If you configure JsonPath to use Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class); To obtain full generics type information, use TypeRef. TypeRef<List<String>> typeRef = new TypeRef<List<String>>() {};
List<String> titles = JsonPath.parse(JSON_DOCUMENT).read("$.store.book[*].title", typeRef); PredicatesThere are three different ways to create filter predicates in JsonPath. Inline PredicatesInline predicates are the ones defined in the path. List<Map<String, Object>> books = JsonPath.parse(json)
.read("$.store.book[?(@.price < 10)]"); You can use You can use Filter PredicatesPredicates can be built using the Filter API as shown below: import static com.jayway.jsonpath.JsonPath.parse;
import static com.jayway.jsonpath.Criteria.where;
import static com.jayway.jsonpath.Filter.filter;
...
...
Filter cheapFictionFilter = filter(
where("category").is("fiction").and("price").lte(10D)
);
List<Map<String, Object>> books =
parse(json).read("$.store.book[?]", cheapFictionFilter); Notice the placeholder Filters can also be combined with 'OR' and 'AND' Filter fooOrBar = filter(
where("foo").exists(true)).or(where("bar").exists(true)
);
Filter fooAndBar = filter(
where("foo").exists(true)).and(where("bar").exists(true)
); Roll Your OwnThird option is to implement your own predicates Predicate booksWithISBN = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
return ctx.item(Map.class).containsKey("isbn");
}
};
List<Map<String, Object>> books =
reader.read("$.store.book[?].isbn", List.class, booksWithISBN); Path vs ValueIn the Goessner implementation a JsonPath can return either Configuration conf = Configuration.builder()
.options(Option.AS_PATH_LIST).build();
List<String> pathList = using(conf).parse(json).read("$..author");
assertThat(pathList).containsExactly(
"$['store']['book'][0]['author']",
"$['store']['book'][1]['author']",
"$['store']['book'][2]['author']",
"$['store']['book'][3]['author']"); Set a valueThe library offers the possibility to set a value. String newJson = JsonPath.parse(json).set("$['store']['book'][0]['author']", "Paul").jsonString(); Tweaking ConfigurationOptionsWhen creating your Configuration there are a few option flags that can alter the default behaviour. DEFAULT_PATH_LEAF_TO_NULL
[
{
"name" : "john",
"gender" : "male"
},
{
"name" : "ben"
}
] Configuration conf = Configuration.defaultConfiguration();
//Works fine
String gender0 = JsonPath.using(conf).parse(json).read("$[0]['gender']");
//PathNotFoundException thrown
String gender1 = JsonPath.using(conf).parse(json).read("$[1]['gender']");
Configuration conf2 = conf.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
//Works fine
String gender0 = JsonPath.using(conf2).parse(json).read("$[0]['gender']");
//Works fine (null is returned)
String gender1 = JsonPath.using(conf2).parse(json).read("$[1]['gender']"); ALWAYS_RETURN_LIST
Configuration conf = Configuration.defaultConfiguration();
//ClassCastException thrown
List<String> genders0 = JsonPath.using(conf).parse(json).read("$[0]['gender']");
Configuration conf2 = conf.addOptions(Option.ALWAYS_RETURN_LIST);
//Works fine
List<String> genders0 = JsonPath.using(conf2).parse(json).read("$[0]['gender']"); SUPPRESS_EXCEPTIONS
REQUIRE_PROPERTIES
Configuration conf = Configuration.defaultConfiguration();
//Works fine
List<String> genders = JsonPath.using(conf).parse(json).read("$[*]['gender']");
Configuration conf2 = conf.addOptions(Option.REQUIRE_PROPERTIES);
//PathNotFoundException thrown
List<String> genders = JsonPath.using(conf2).parse(json).read("$[*]['gender']"); JsonProvider SPIJsonPath is shipped with five different JsonProviders:
Changing the configuration defaults as demonstrated should only be done when your application is being initialized. Changes during runtime is strongly discouraged, especially in multi threaded applications. Configuration.setDefaults(new Configuration.Defaults() {
private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();
@Override
public JsonProvider jsonProvider() {
return jsonProvider;
}
@Override
public MappingProvider mappingProvider() {
return mappingProvider;
}
@Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
}); Note that the JacksonJsonProvider requires Both of Jakarta EE 9 JSON-P (JSR-342) and JSON-B (JSR-367) providers expect at least Java 8 and require compatible JSON API implementations (such as Eclipse Glassfish and Eclipse Yasson) on application runtime classpath; such implementations may also be provided by Java EE application container. Please also note that Apache Johnzon is not classpath-compatible with Jakarta EE 9 specification yet, and if JSON-B mapping provider is chosen then JSON-P provider must be configured and used, too. One peculiarity of Jakarta EE 9 specifications for JSON processing and databinding (mapping) is immutability of Json arrays and objects as soon as they are fully parsed or written to. To respect the API specification, but allow JsonPath to modify Json documents through add, set/put, replace, and delete operations,
All lookup and read operations with JsonPath are supported regardless of initilization mode. Default mode also needs less memory and is more performant. Cache SPIIn JsonPath 2.1.0 a new Cache SPI was introduced. This allows API consumers to configure path caching in a way that suits their needs. The cache must be configured before it is accesses for the first time or a JsonPathException is thrown. JsonPath ships with two cache implementations
If you want to implement your own cache the API is simple. CacheProvider.setCache(new Cache() {
//Not thread safe simple cache
private Map<String, JsonPath> map = new HashMap<String, JsonPath>();
@Override
public JsonPath get(String key) {
return map.get(key);
}
@Override
public void put(String key, JsonPath jsonPath) {
map.put(key, jsonPath);
}
}); |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论