Parsing deeply nested JSON properties with Jackson

sam :

I am trying to find a clean way of parsing nested properties from a payload from an API.

Here is a rough generalisation of the JSON payload:

{
  "root": {
    "data": {
      "value": [
        {
          "user": {
            "id": "1",
            "name": {
              "first": "x",
              "last": "y"
            }
          }
        }
      ]
    }
  }
}

My goal is to have an array of User objects which have firstName and lastName fields.

Does anyone know a good way to parse this cleanly?

Right now I am trying to create a Wrapper class and within that have static inner classes for data, value, user etc. but this seems like a messy way of doing this just to read the array of first/last properties.

I am using restTemplate.exchange() to call the endpoint.

Michał Ziober :

You need to use JsonPath library which allow you to select only required fields and after that you can use Jackson to convert raw data to POJO class. Example solution, could look like below:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.jayway.jsonpath.JsonPath;

import java.io.File;
import java.util.List;
import java.util.Map;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        List<Map> nodes = JsonPath.parse(jsonFile).read("$..value[*].user.name");

        ObjectMapper mapper = new ObjectMapper();
        CollectionType usersType = mapper.getTypeFactory().constructCollectionType(List.class, User.class);
        List<User> users = mapper.convertValue(nodes, usersType);
        System.out.println(users);
    }
}

class User {

    @JsonProperty("first")
    private String firstName;

    @JsonProperty("last")
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "User{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

Above code prints:

[User{firstName='x', lastName='y'}]

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=165475&siteId=1