杰克逊结合@JsonIdentityInfo和@JsonTypeInfo引发InvalidTypeIdException

目前,当我将@JsonIdentityInfo@JsonTypeInfo结合使用时,杰克逊遇到了问题。下面的Kotlin代码在最后一行抛出异常。它按预期将dog1AndDog1Json实例序列化为Json,但随后在将其反序列化为实例时抛出异常。

package some.test

import com.fasterxml.jackson.annotation.*
import com.fasterxml.jackson.databind.ObjectMapper

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
@JsonSubTypes(JsonSubTypes.Type(value = Dog::class),JsonSubTypes.Type(value = Cat::class))
interface Animal {
    val name: String
}

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator::class)
data class Dog(@JsonProperty("name") override val name: String) : Animal

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator::class)
data class Cat(@JsonProperty("name") override val name: String) : Animal

data class TwoAnimals(@JsonProperty("animal1") val animal1: Animal,@JsonProperty("animal2") val animal2: Animal)

fun main() {
    val om = ObjectMapper();

    val dog1 = Dog("Dog1")
    val dog2 = Dog("Dog2")
    val cat1 = Cat("Cat1")

    val dog1AndDog2 = TwoAnimals(dog1,dog2)
    val dog1AndDog2Json = om.writerWithDefaultPrettyPrinter().writeValueAsString(dog1AndDog2)
    assert(dog1AndDog2 === om.readValue(dog1AndDog2Json,TwoAnimals::class.java)) // OK

    val dog1AndCat1 = TwoAnimals(dog1,cat1)
    val dog1AndCat2Json = om.writerWithDefaultPrettyPrinter().writeValueAsString(dog1AndCat1)
    assert(dog1AndCat1 === om.readValue(dog1AndCat2Json,TwoAnimals::class.java)) // OK

    val dog1AndDog1 = TwoAnimals(dog1,dog1)
    val dog1AndDog1Json = om.writerWithDefaultPrettyPrinter().writeValueAsString(dog1AndDog1)
    println(dog1AndDog1Json)
    assert(dog1AndDog1 === om.readValue(dog1AndDog1Json,TwoAnimals::class.java)) // DESERIALIZE FAILS
}

然后我运行以下输出的主函数:

{
  "animal1" : {
    "@class" : "some.test.Dog","@id" : 1,"name" : "Dog1"
  },"animal2" : 1
}

此异常之后:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type,class some.test.Animal]: missing type id property '@class' (for POJO property 'animal2')
 at [Source: (String)"{
  "animal1" : {
    "@class" : "some.test.Dog","animal2" : 1
}"; line: 7,column: 15] (through reference chain: some.test.TwoAnimals["animal2"])
    at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
<truncated rest of stacktrace>

似乎Jackson希望animal2属性的对象具有@class属性,以找到要反序列化的正确类类型。但是它已被@JsonIdentityInfo注释替换为ID。为什么杰克逊不通过该ID查找对象,然后检查该实例的@class属性?

我不确定Jackson是否不支持该用例,或者我做错了什么(我希望什么)。或者也许是一个错误?

xuxianbing11 回答:杰克逊结合@JsonIdentityInfo和@JsonTypeInfo引发InvalidTypeIdException

我设法通过以下方式使它起作用:

  1. @JsonIdentityInfoDog子类中删除Car注释
  2. @JsonIdentityInfo基类添加Animal
本文链接:https://www.f2er.com/2962525.html

大家都在问