有一个json对象,其字段之一是一个json字符串,其中包含一个序列化的json对象,需要反序列化为多态类型。如何使用杰克逊注释来做到这一点?使用的版本是 Jackson 2.14.0。
如果在代码级别,那么您需要以某种方式更改data class以使测试通过:
data class Zoo(
val animal: Animal
)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes(
JsonSubTypes.Type(Cat::class, name = "cat"),
JsonSubTypes.Type(Dog::class, name = "dog"),
)
interface Animal
data class Cat(
val meow: String,
) : Animal
data class Dog(
val woof: String,
) : Animal
class TestDeser {
private val objectMapper: ObjectMapper = ObjectMapper().findAndRegisterModules()
@Test
fun testDeserialize() {
val catJson = "{\"animal\":\"{\\\"type\\\":\\\"cat\\\",\\\"meow\\\":\\\"catValue\\\"}\"}"
val dogJson = "{\"animal\":\"{\\\"type\\\":\\\"dog\\\",\\\"woof\\\":\\\"dogValue\\\"}\"}"
val zooWithCat = this.objectMapper.readValue<Zoo>(catJson)
val cat = zooWithCat.animal
Assertions.assertTrue(cat is Cat)
cat as Cat
Assertions.assertEquals("catValue", cat.meow)
val zooWithDog = this.objectMapper.readValue<Zoo>(dogJson)
val dog = zooWithDog.animal
Assertions.assertTrue(dog is Dog)
dog as Dog
Assertions.assertEquals("dogValue", dog.woof)
}
}
我尝试过的:
我尝试编写自己的
JsonDeserializer:class MyDeserializer : StdDeserializer<Animal>(Animal::class.java) { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Animal { val str = p.valueAsString return (p.codec as ObjectMapper).readValue(str) } } data class Zoo( @JsonDeserialize(using = MyDeserializer::class) val animal: Animal, )我将这种方法用于常规类型,而不是多态类型,并且它有效。对于多态类型,
deserialize它甚至不进入方法。我想尝试使用
Converterclass MyConverter : StdConverter<String, Animal>() { override fun convert(value: String): Animal { TODO("Нет доступа к ObjectMapper :(") } } data class Zoo( @JsonDeserialize(converter = MyConverter::class) val animal: Animal, )但如果使用转换器
ObjectMapper,则无法将字符串转换为 POJO
