如何使用 Jackson 解析 JSON 对象数组?

How to parse a JSON array of objects using Jackson?

我有一个 Json 回复如下:

   {
      "data": {
        "date": "7 Apr 2022",
        "employee": [
          {
            "id": [
              "1288563656"
            ],
            "firstname": [
              "Mohammed"
            ],
            "lastname": [
              "Ali"
            ]
          }
        ]
      }
    }

我正在尝试创建一个名为 Employee 的 POJO 并将其映射到 JSON 响应中的“employee”属性。

这是我尝试做的:

Employee.java

public class Emoloyee {
    private Integer[] id;
    private String[] firstname;
    private String[] lastname;
    
    public Employee(Integer[] id, String[] firstname, String[] lastname){
        this.id = id;
        this.firstname = firstname;
        this.lastname = lastname;
    }
    
    public Employee(){
        
    }
    
    public Integet[] getId(){
        return id;
    }
    
    public void setId(Integer[] id){
        this.id = id;
    }
    
    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;
    }
    
}

使用杰克逊:

ObjectMapper mapper = new ObjectMapper();
URL jsonUrl = new URL("[API_URL]");
final ObjectNode node = mapper.readValue(jsonUrl, ObjectNode.class);
Employee[] employees = mapper.treeToValue(node.get("data").get("employee"), Employee[].class);

当我执行应用程序时,出现以下错误:

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type 'long' from Array value (toke 'JsonToken.START_ARRAY')

您可能已经注意到,我对 date 属性不感兴趣,我只需要获取员工的值并从中创建一个 Employee 对象。

Employee POJO 应该如下所示:

@JsonProperty("id")
private final List<String> ids;
@JsonProperty("firstname")
private final List<String> firstNames;
@JsonProperty("lastname")
private final List<String> lastNames;

@JsonCreator
public Employee(@JsonProperty(value = "id") List<String> ids, @JsonProperty(value = "firstname") List<String> firstNames, @JsonProperty(value = "lastname") List<String> lastNames) {
    this.ids = ids;
    this.firstNames = firstNames;
    this.lastNames = lastNames;
}

//getters code

那么,你有一个对象Data:

@JsonProperty("date")
private final String date;
@JsonProperty("employee")
private final List<Employee> employees;

@JsonCreator
public Data(@JsonProperty(value = "date") String date, @JsonProperty(value = "employee") List<Employee> employees) {
    this.date = date;
    this.employees = employees;
} 

//getters code

最后,您要解析的整个 Answer 具有以下形状:

@JsonProperty("data")
private final Data data;

@JsonCreator
public Answer(@JsonProperty(value = "data") Data data) {
    this.data = data;
} 

//getter code

一旦你定义了这 3 个类,那么你将能够做到:

ObjectMapper objectMapper = new ObjectMapper();
Answer answer = objectMapper.readValue(yourStringAnswer, Answer.class);

注意:在您的问题中,您试图将 URL 解析为 ObjectNode。我几乎不怀疑你能做到这一点。 我猜您想对 URL 执行 HTTP 请求,然后获取响应流,这就是您要解析为 Answer 的内容(而不是 URL 本身)。

此外,关于 API 回复的一些说明(如果您拥有它并可以根据它采取行动):

  • 所有列表将更自然地用复数名称声明(例如 employee 应该是 employees
  • ids 的列表是数字,但作为字符串返回。另外,为什么员工会有一个 ID 列表,而不是一个 ID?
  • 为什么员工会有名字和姓氏列表?这不应该是每个简单的字符串(即使由多个名称组成)吗?
  • 使用驼峰式大小写(firstName,而不是 firstname
  • 我看不出将所有内容都放入 data 的意义,它可能只是包含 dateemployees
  • 的响应