jackson 处理多态类型需提前声明合法子类、标识字段及位置,核心靠 @jsontypeinfo 和 @jsonsubtypes 注解驱动;必须在基类/接口上配置,类型字段名需前后端一致;禁用不安全的全局 defaulttyping,推荐白名单控制;泛型集合需封装类承载类型信息;未匹配 type 时可用 defaultimpl 提供兜底实现。

用 Jackson 的 ObjectMapper 处理多态类型,关键不是“怎么让 ObjectMapper 识别子类”,而是**提前告诉它哪些子类合法、用什么字段标识类型、以及类型信息放在哪儿**。核心靠注解驱动,不是运行时猜测。
在基类或接口上声明类型识别规则
必须在抽象类、接口或父类上使用 @JsonTypeInfo 和 @JsonSubTypes,否则 Jackson 不知道该为谁加类型字段。
-
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type"):表示用字符串名称标识类型,类型名作为 JSON 中的普通字段(如"type": "dog") -
@JsonSubTypes列出所有允许的子类及对应名称,例如:@JsonSubTypes({<br> @Type(value = Dog.class, name = "dog"),<br> @Type(value = Cat.class, name = "cat")<br>}) - 字段名(如
property = "type")要和实际 JSON 中的键一致,前后端需约定好
避免全局默认类型启用带来的安全隐患
虽然可以调用 activateDefaultTyping() 让 ObjectMapper 自动为所有非 final 类加类型信息,但不推荐用于生产环境。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 它会暴露完整类名(如
"@class": "com.example.Dog"),容易被恶意利用反序列化任意类 - 应配合
PolymorphicTypeValidator严格限制可反序列化的包路径,例如只允许com.example.model.* - 更安全的做法是显式注解 + 白名单控制,而非依赖全局策略
处理泛型集合或多层嵌套时的常见陷阱
当多态对象出现在 List 或 Map 中,或者作为某个字段的值时,Jackson 无法自动把类型信息“传递”到泛型参数上。
- 不能直接对
List<animal></animal>做多态反序列化——@JsonTypeInfo必须作用于一个具体类,比如封装了List<animal></animal>的响应包装类 - 如果类型标识在父级 JSON 字段中(如
"method": "account"决定"data"是哪种列表),要用include = As.EXTERNAL_PROPERTY并指定property = "method" - 确保每个参与多态的类都有无参构造器,否则反序列化会失败
反序列化时未匹配子类的兜底方案
客户端传了一个服务端不认识的 type 值(比如 "type": "bird"),默认会抛 JsonMappingException。
- 可在
@JsonTypeInfo中添加defaultImpl = UnknownAnimal.class,提供一个兜底实现类 - 该类需继承基类或实现接口,并能接受未知字段(建议用
@JsonAnySetter收集多余字段) - 注意
visible = true可让 type 字段也映射到对象属性中,便于日志记录或路由判断
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










