如何反序列化一个复杂的 JSON

How to deserialize a complex JSON

我是 Jackson 的新手,我需要反序列化 JSON 如下所示:

{
  "companies": [{
    "id": "some_id",
    "type": "sale",
    "name": "Company1",
    "attributes": {
      "countPeople": 300,
      "salary": 3000
    }
  }, 
  {
    "id": "new_id",
    "type": "IT",
    "name": "Company2",
    "attributes": {
      "countPeople": 100,
      "salary": 5000,
      "city": "New York",
      ...
    }
  }]
}

我想将其反序列化为 DTO,如下所示:

public class Companies {
    @JsonProperty("companies")
    public List<Company> companiesList;
}

public class Company {
    public String id;
    public String type;
    public String name;
    public Attributes attributes;
    
    @JsonCreator
    public Company(@JsonProperty("id") String id,
                   @JsonProperty("type") String type,
                   @JSonProperty("name") String name,
                   @JsonProperty("attributes") Attributes attributes
    ) {
        ...
    }
}

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type"
)
@JsonSubTypes({
        @JsonSubTypes.Type(name = "IT", value = ItAttributes.class)
        ...
})
public abstract Attributes {
    public int countPeople;
    ...
}

public class ItAttributes extends Attributes {
   ...
}

当我试图反序列化 JSON

public class Main {
    public static void main(String... args) {
        ObjectMapper mapper = new ObjectMapper();
        Companies comp = mapper.readValue(json, Companies.class);
    }
}

我遇到了异常:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.example.dto.Attributes]: missing type id property 'type' (for POJO property 'attributes')

显然 Jackson 没有看到 type 属性,但我不明白为什么。
我该如何解决这个问题?

您实际上需要在摘要 Company 中使用 @JsonTypeInfo@JsonSubTypes,如下所示:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type"
)
@JsonSubTypes({
        @JsonSubTypes.Type(name = "IT", value = ItCompany.class)
        ...
})
public abstract Company {
    public String id;
    public String type;
    public String name;
}

那么您将拥有具体的 Company 实现:

public class ItCompany {
    public ItAttributes attributes;
}

// Other Company types

而您的 Attributes class 将如下所示:

public abstract Attributes {
    public int countPeople;
    ...
}

public class ItAttributes extends Attributes {
   ...
}