使用 Jackson 将不同数量的对象反序列化为 Java 中的列表

Deserialize a varying number of objects into a list in Java using Jackson

我的 Spring 引导应用程序调用 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 到很多房客,我不知道他们的人数。如您所见,它们不在数组中,而是对象。

我想避免反序列化为 class 之类的

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。你能帮帮我吗?

@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