Jackson反序列化抽象类子类失败:缺失_class类型标识问题排查
问题分析与解决方案
你的问题出在Jackson类型识别注解的配置不匹配,导致反序列化时无法识别抽象类DataExport的具体子类。以下是具体原因和修复方案:
核心问题
你在DataExport上配置了@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS),这表示Jackson期望请求体中的_class字段值是子类的全限定类名(如ru.rivc.crew.crewdata.optimizer.export.dto.dataexport.AirportExport),但同时又在@JsonSubTypes中给子类设置了自定义别名(如AirportExport),两者逻辑冲突,导致Jackson无法正确解析类型标识。
修复方案(二选一)
方案1:使用全限定类名作为类型标识
保持现有@JsonTypeInfo配置不变,请求体中传入子类的完整类名即可:
- 抽象类注解无需修改:
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="_class") @JsonSubTypes({ @JsonSubTypes.Type(value = AirportExport.class, name = "AirportExport"), @JsonSubTypes.Type(value = TimeTableExport.class, name = "TimeTableExport")} ) public abstract class DataExport { private DataType dataType; }
- 请求体示例:
{ "data": [ { "_class": "ru.rivc.crew.crewdata.optimizer.export.dto.dataexport.AirportExport", "dataType": "AIRPORT" } ] }
注:此方案下@JsonSubTypes配置可省略,Jackson会直接通过全类名匹配子类
方案2:使用自定义别名作为类型标识(更友好)
修改@JsonTypeInfo的use属性为JsonTypeInfo.Id.NAME,让Jackson使用@JsonSubTypes中配置的别名作为类型标识:
- 修改抽象类注解:
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="_class") @JsonSubTypes({ @JsonSubTypes.Type(value = AirportExport.class, name = "AirportExport"), @JsonSubTypes.Type(value = TimeTableExport.class, name = "TimeTableExport")} ) public abstract class DataExport { private DataType dataType; }
- 请求体示例:
{ "data": [ { "_class": "AirportExport", "dataType": "AIRPORT" } ] }
额外注意事项
- 确保请求体中每个
data数组元素都包含_class字段,且字段位置与其他属性同级; - 子类需保证存在无参构造函数(你的
AirportExport使用@Getter@Setter,编译器会自动生成默认无参构造,符合要求); - 若使用Lombok,子类可直接添加
@Data注解,简化代码编写。
内容的提问来源于stack exchange,提问作者Дмитрий Рудов
相关产品推荐
相关产品推荐

