Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

java - Parsing deeply nested JSON properties with Jackson

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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'}]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...