使用Jackson

时间:2018-11-26 14:34:18

标签: java jackson deserialization json-deserialization

我的Spring Boot应用程序调用REST API,并接收具有不同数量实体的JSON。例如

{
  "content": {
    "guest_1": {
      "name": {
        "firstName": "a",
        "lastName": "b"
      },
      "vip": false
    },
    "guest_2": {
      "name": {
        "firstName": "c",
        "lastName": "d"
      },
      "vip": false
    },
    ...more guests omitted...
  }
}

最多可以有1位客人,我不知道他们的提前人数。如您所见,它们不在数组中,而是对象。

我想避免反序列化为类似的类

public class Content {

  @JsonProperty("guest_1")
  private Guest guest1;

  @JsonProperty("guest_2")
  private Guest guest2;

  // More Guests here each having their own field
}

我想使用的是

public class Content {

  private List<Guest> guests;
}

我在https://www.baeldung.com/jackson-annotations读到的@JsonAnySetter注释看起来很有希望,但我无法使其正常工作。

3.2。在https://www.baeldung.com/jackson-json-node-tree-model处转换为对象看起来也不错,但是也没有用。

我不确定是否可以让Jackson声明性地执行此操作,还是应该编写自定义的JsonDeserializer。你能帮我吗?

1 个答案:

答案 0 :(得分:1)

@JsonAnySetter将起作用,因为它允许将POJO类型指定为第二个参数。您可以重新创建示例JSON,为清楚起见,在POJO上省略了setXXX()getXXX()方法:

private static class Content {
    private Guests content;
}

private static class Guests  {
    private List<Guest> guests = new ArrayList<>();

    @JsonAnySetter
    private void addGuest(String name, Guest value) {
        guests.add(value);
    }
}

private static class Guest {
    private Name name;
    private boolean vip;
}

private static class Name {
    private String firstName;
    private String lastName;
}

使用您的JSON示例将产生:

Content root = new ObjectMapper().readValue(json, Content.class);
root.getContent().getGuests().stream()
        .map(Guest::getName)
        .map(Name::getFirstName)
        .forEach(System.out::println); // a, c