You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中使用Jackson实现多级继承的多态反序列化问题

解决Jackson多级继承的多态反序列化问题

问题原因

你当前的配置仅能完成一级类型解析(从Vehicle到Car),因为Jackson在确定父类的具体类型后,默认不会触发子类上的@JsonTypeInfo注解,导致无法进一步实例化到Sedan。

解决方案

通过调整注解配置,让Jackson支持多级类型解析,核心是确保每个层级的类型注解都能被触发,同时保留类型字段的可见性。

1. 修改Vehicle类的注解

添加visible = true参数,确保vehicleType字段不会被Jackson隐藏,不影响后续子类的字段解析:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "vehicleType",
        visible = true // 保留类型字段,确保后续解析正常进行
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Car.class, name = "car")
})
public class Vehicle {
    public String vehicleType; // 确保字段可访问,或提供getter/setter方法
}

2. 修改Car类的注解

同样添加visible = true,并配置Sedan的类型映射:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "carType",
        visible = true
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Sedan.class, name = "sedan")
})
public class Car extends Vehicle {
    public String carType;
    public String make;
}

3. Sedan类保持不变

确保字段可访问:

public class Sedan extends Car {
    public String model;
}

测试验证

运行你提供的测试代码,Jackson会先根据vehicleType解析到Car,接着根据carType进一步解析到Sedan,断言会成功:

ObjectMapper mapper = new ObjectMapper();
Vehicle myVehicle = mapper.readValue(inputData, Vehicle.class);
Assertions.assertInstanceOf(Sedan.class, myVehicle);

补充说明

  • visible = true的作用是让Jackson在解析后保留类型字段(如vehicleType、carType),不会将其从反序列化对象中移除,同时确保子类的类型注解能正常读取对应字段。
  • 所有需要反序列化的字段需设为public,或提供对应的getter/setter方法,否则Jackson无法访问字段完成赋值。

内容的提问来源于stack exchange,提问作者qstack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:57:09