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
相关产品推荐
相关产品推荐

