尝试反序列化子类时“com.fasterxml.jackson.databind.exc.InvalidTypeIdException:无法解析类型 ID”

Posted

技术标签:

【中文标题】尝试反序列化子类时“com.fasterxml.jackson.databind.exc.InvalidTypeIdException:无法解析类型 ID”【英文标题】:"com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id" when trying to deserialise subclass 【发布时间】:2021-12-30 06:17:45 【问题描述】:

我正在尝试实现 JsonSubTypes,但我希望能够对无法识别的子类型进行一些优雅的处理。我正在使用 Jackson 2.9.7,并且更新不是一个选项,因为还有一些其他类取决于它。

假设这是我的代码:

@Value.Style(allParameters = true, typeImmutable = "*", typeImmutableEnclosing = "*Impl",
    defaults = @Value.Immutable(builder = false))
@Value.Enclosing
@JsonSerialize
@JsonDeserialize
public class JsonAnimal 


  @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "subClass", include = JsonTypeInfo.As.EXISTING_PROPERTY,
      visible = true, defaultImpl = UnmappedAnimal.class) //fixme create logger warning if this defaults to a Void
  @JsonSubTypes(
      @JsonSubTypes.Type(value = Dog.class, name = Dog.ANIMAL_TYPE),
      @JsonSubTypes.Type(value = Cat.class, name = Cat.ANIMAL_TYPE),
      @JsonSubTypes.Type(value = Fish.class, name = Fish.ANIMAL_TYPE),
      @JsonSubTypes.Type(value = Hamster.class,
          name = Hamster.ANIMAL_TYPE)
  public static abstract class Animal 
    public abstract String subClass();
    //other code
  
  @Value.Immutable
  @JsonDeserialize
  public abstract static class Dog extends Animal 
    public static final String ANIMAL_TYPE = "dog";
    //dog-specific code
  

  @Value.Immutable
  @JsonDeserialize
  public abstract static class Cat extends Animal 
    public static final String ANIMAL_TYPE = "cat";
    //cat-specific code
  

  @Value.Immutable
  @JsonDeserialize
  public abstract static class Fish extends Animal 
    public static final String ANIMAL_TYPE = "fish";
    //fish-specific code
  

  @Value.Immutable
  @JsonDeserialize
  public abstract static class Hamster extends Animal 
    public static final String ANIMAL_TYPE = "hamster";
    //hamster-specific code
  

  public class UnmappedAnimal extends Animal  /**/ 

我实现了子类,因为 JSON 有效负载中的“动物”对象将具有不同的字段,具体取决于“子类”的值,例如子类“cat”的动物将具有其他子类没有的“livesLeft”字段。

现在假设我收到了这个 JSON 有效负载:


  "id": 123456,
  "animal": 
    "subType": "horse",
    /* everything else */
  

这会导致以下错误:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'horse' as a subtype of [simple type, class my.project.path.apiobject.JsonAnimal$Animal]: known type ids = dog, cat, fish, hamster] (for POJO property 'animal')

我该怎么做才能处理未映射的子类型?解析 JSON 时我应该只使用catch (InvalidTypeIdException) 吗?对此我能得到任何帮助,我将不胜感激。

编辑: 我还应该问,我的 JSON 解析器的 ObjectMapper 启用了 ACCEPT_CASE_INSENSITIVE_PROPERTIES 和 FAIL_ON_UNKNOWN_PROPERTIES,但是如果我有一个名为“SubClass”而不是“subClass”的属性,则不会被解析。

【问题讨论】:

【参考方案1】:

如果你像这样配置你的 objectMapper 实现

objectMapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);

您可以实现优雅的处理。具有不可解析子类型的字段将被反序列化为 null。

【讨论】:

谢谢,错误已停止。

以上是关于尝试反序列化子类时“com.fasterxml.jackson.databind.exc.InvalidTypeIdException:无法解析类型 ID”的主要内容,如果未能解决你的问题,请参考以下文章

如果父类实现了Serializable并生成了serialVersionUID,而子类并没有写重新生成serialVersionUID的语句?

根据字段值反序列化为密封子类

序列化---Serializable与Externalizable源码

使用 Jackson 序列化通用接口子类

当我尝试从 c# 中的 url 反序列化时出错

当我尝试反序列化对象列表时,杰克逊抛出错误映射异常