如何使用Jackson mapper自动识别不同类型反序列化为AnimalDTO
问题根因分析
你当前的多态注解配置完全用错了场景:@JsonTypeInfo + @JsonSubTypes 这套注解是为了解决父类类型字段反序列化为对应子类实例的问题,仅当你的容器类里用父类类型接收不确定的子类实例时才需要,比如:
// 父类标注多态规则 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @Type(value = CatDTO.class, name = "cat"), @Type(value = DogDTO.class, name = "dog") }) public class Animal {} // 子类继承父类 public class CatDTO extends Animal {} public class DogDTO extends Animal {} // 容器类用父类类型声明字段 public class AnimalDTO { private boolean error; private String errorMessage; private Animal animal; // 字段是父类类型,实际可能是Cat或Dog }
但你现有的AnimalDTO是直接定义了cat、dog两个明确类型的独立字段,Jackson可以直接根据字段名匹配对应类型完成反序列化,完全不需要多态配置,你加的注解和现有结构不匹配,当然不会生效。
除此之外你的代码还有两处语法错误,会直接导致反序列化失败:
AnimalDTO的构造函数名拼写错误:类名是AnimalDTO,构造函数写为AnimalDTODTO,多了DTO后缀,Jackson找不到正确的实例化入口DogDTO的构造函数参数之间缺少逗号分隔,dogState、dogColor参数后都没有加逗号,属于Java语法错误,编译都无法通过
最优处理方案
按以下步骤调整即可直接使用objectMapper.readValue(stringJson, AnimalDTO.class)完成自动反序列化:
- 删掉加在
AnimalDTO上的@JsonTypeInfo、@JsonSubTypes注解,完全不需要 - 修正
AnimalDTO的构造函数名,和类名保持一致:public AnimalDTO(...) - 补全
DogDTO构造函数参数之间的逗号,修正语法错误 - 确保接口返回的完整JSON结构匹配
AnimalDTO的字段定义,示例如下:
{ "error": false, "errorMessage": null, "cat": { "catNumber": "1", "catState": "good" }, "dog": { "dogNumber": "23", "dogState": "good", "dogColor": "pink", "dogBalance": 5 } }
如果接口返回时只会存在cat和dog其中一个,另一个为null,Jackson也可以正常反序列化,不需要额外配置。
内容的提问来源于stack exchange,提问作者FPerez
相关产品推荐
相关产品推荐

