Reputation: 3296
I am getting a big json document and i want to parse only some part of it to my java classes. I was thinking to use something like jsonpath to extract partial data from it instead of creating entire hierarchy of java classes.
Does Jackson or Gson support jsonpath in any way? If yes, can you please provide me some examples or point to another standard library for this purpose?
For example lets say i have a below document and i want to extract only below data from it in my java classes:
$.store.book[0] - Only first book $.store.bicycle.price - price of bicycle
{
"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
}
Upvotes: 48
Views: 77867
Reputation: 5443
String json = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"address\":{\"street\":"
+ "\"21 2nd Street\",\"city\":\"New York\",\"postalCode\":\"10021-3100\","
+ "\"coordinates\":{\"latitude\":40.7250387,\"longitude\":-73.9932568}}}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(json);
JsonNode coordinatesNode = node.at("/address/coordinates");
This is a JSON Pointer
approach which I found here: https://cassiomolin.com/2016/07/13/using-jackson-and-json-pointer-to-query-and-parse-an-arbitrary-json-node/
Upvotes: 53
Reputation: 13907
The Jayway JsonPath library has support for reading values using a JSON path.
For example:
String json = "...";
Map<String, Object> book = JsonPath.read(json, "$.store.book[0]");
System.out.println(book); // prints {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}
Double price = JsonPath.read(json, "$.store.bicycle.price");
System.out.println(price); // prints 19.95
You can also map JSON objects directly to classes, like in GSON or Jackson:
Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);
System.out.println(book); // prints Book{category='reference', author='Nigel Rees', title='Sayings of the Century', price=8.95}
If you would like to specifically use GSON or Jackson to do the deserialization (the default is to use json-smart), you can also configure this:
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);
}
});
See the documentation for more details.
Upvotes: 51