suraj bahl
suraj bahl

Reputation: 3296

Jsonpath with Jackson or Gson

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

Answers (2)

Ashley Frieze
Ashley Frieze

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

andersschuller
andersschuller

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

Related Questions