在没有类标识符的情况下显式反序列化一个子类

编程语言 2026-07-11

在Jackson中,我有一个接口和子类,之前只是在显式序列化/反序列化时使用。我正在尝试做一个改动,允许直接序列化/反序列化该接口,并添加了 @JsonSubTypes@JsonTypeInfo 注解。

@JsonSubTypes({
  @JsonSubTypes.Type(
      value = DataProcessingJob.class,
      name = "data_processing_job")
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
public interface JobDefinition {
...
}

public record DataProcessingJob() implements JobDefinition {
...
}
private static final ObjectMapper OBJECT_MAPPER =
      Json.mapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
OBJECT_MAPPER.readValue(jsonBlob, DataProcessingJob.class);

这对于以这种格式序列化作业是有效。不过数据库中仍然有一些旧的作业没有 type 属性,因此会产生如下错误:

原因:com.fasterxml.jackson.databind.exc.InvalidTypeIdException: 无法解析子类型 [simple type, class models.job.DataProcessingJob]:缺少类型标识属性 'type'

这很合理,这些作业没有类型标识 type

然而,有没有办法让Jackson在没有 type 注解的情况下对这些旧作业进行反序列化?在这个示例中,我们已经知道要序列化到的类型是 DataProcessingJob

可以在JSON本身没有类型标识属性的情况下,显式地反序列化一个子类吗?

解决方案

Jackson正在强制 @JsonTypeInfo,即使你传入的是具体的类,因此它仍然期望 "type"

如果你希望旧JSON(没有 "type")也能工作,请添加一个回退机制:

@JsonTypeInfo(
  use = JsonTypeInfo.Id.NAME,
  include = JsonTypeInfo.As.PROPERTY,
  property = "type",
  defaultImpl = DataProcessingJob.class
)

这让Jackson将缺失的 "type" 反序列化为 DataProcessingJob

不过,如果你有多个子类型,这种推测可能会出错,在这种情况下,最好迁移旧数据,或通过手动的回退读取来处理。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章