如何使用杰克逊映射器自动识别不同的类型

Posted

技术标签:

【中文标题】如何使用杰克逊映射器自动识别不同的类型【英文标题】:How to identify different types automatically using Jackson mapper 【发布时间】:2022-01-03 12:32:48 【问题描述】:

我有一个简单的情况。我有一个包含以下字段的主要 DTO 类: AnimalDTO

public class AnimalDTO 
    @JsonCreator
    public AnimalDTODTO(@JsonProperty("error") boolean error,
                                       @JsonProperty("errorMessage") String errorMessage,
                                       @JsonProperty("cat") CatDTO cat,
                                       @JsonProperty("dog") DogDTO dog) 
        this.error = error;
        this.errorMessage = errorMessage;
        this.cat = cat;
        this.dog = dog;
    

    private boolean error;
    private String errorMessage;
    private CatDTO cat;
    private DogDTO dog;

CatDTO:

public class CatDTO 
    @JsonCreator
    public CatDTO(@JsonProperty("catNumber") String catNumber,
                  @JsonProperty("catState") String catState) 
        this.catNumber = catNumber;
        this.catState = catState;
    

    private String catNumber;
    private String catState;

DogDTO:

public class DogDTO 
    @JsonCreator
    public DogDTO(@JsonProperty("dogNumber") String dogNumber,
                  @JsonProperty("dogState") String dogState
                  @JsonProperty("dogColor") String dogColor
                  @JsonProperty("dogBalance") BigDecimal dogBalance) 
        this.dogNumber = dogNumber;
        this.dogState = dogState;
        this.dogColor = dogColor;
        this.dogBalance = dogBalance;
    

    private String dogNumber;
    private String dogState;
    private String dogColor;
    private BigDecimal dogBalance;


我从外部 API 获得了 dog 的响应(我无法更改),例如:


   "dogNumber": "23",
   "dogState": "good",
   "dogColor": "pink",
   "dogBalance": 5

对于


   "catNumber": "1",
   "catState": "good"

我想像这样使用 Jackson 映射器:objectMapper.readValue(stringJson, AnimalDTO.class);

我正在考虑添加 AnimalDTO

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME, 
  include = JsonTypeInfo.As.PROPERTY, 
  property = "type")
@JsonSubTypes( 
  @Type(value = CatDTO.class, name = "cat"), 
  @Type(value = DogDTO.class, name = "dog") 
)

但它不起作用。

如何以最佳方式处理我的案件?

【问题讨论】:

你向我们展示了猫 json 和狗 json……你有动物 json 吗?还是这2个JSONS完全独立?? @SMA - 不,我没有动物 json...这 2 个 JSONS 完全独立 那么如果我没记错的话,你需要为每个人创建一个 DTO,你不能使用JsonTypeInfo。根据我的理解 JsonTypeInfoJsonSubTypes 在您的 JSON 中有继承时使用。在您的情况下,每个 JSON 都有完全不同的变量.... 由于两个类是独立的(没有继承层次结构)你不需要@JsonTypeInfo 也不需要@JsonSubTypes。您可以直接将 animal json 序列化/反序列化为 AnimalDTO,这将分别具有 CatDTODogDTO 【参考方案1】:

如果您从外部 API 获得的 JSON 如下所示,您的代码将可以正常工作(没有任何 @JsonTypeInfo@JsonSubTypes 注释):


  "dog": 
    "dogNumber": "23",
    "dogState": "good",
    "dogColor": "pink",
    "dogBalance": 5
  ,
  "cat": 
    "catNumber": "1",
    "catState": "good"
  

如果这看起来与您收到的 JSON 不相似,那么您需要将其添加到您的答案中,以便我们可以进一步帮助您。

【讨论】:

以上是关于如何使用杰克逊映射器自动识别不同的类型的主要内容,如果未能解决你的问题,请参考以下文章

Datastax Cassandra java 驱动程序 - 对象映射器 - 自动创建表

带有 EF 和自动映射器的 OData:无法比较..'。仅支持原始类型、枚举类型和实体类型

杰克逊映射器在三星 SM-T580 上抛出“冲突的二传手定义”

如何在使用自动映射器时将属性名称的 jsonproperty 设置为 dto?

简单的自动映射器示例

使用自动映射器映射对象列表