Kotlin 如何从父对象确定Jackson多态反序列化的类型
我有一个模型,不控制将子类型嵌套在父类中的模型,例如:Kotlin 如何从父对象确定Jackson多态反序列化的类型,kotlin,jackson,Kotlin,Jackson,我有一个模型,不控制将子类型嵌套在父类中的模型,例如: { timestamp: 0, type: { eventType: "Foo" majorVersion: 1 minorVersion: 0 }, data: { foo: "baz" } } 现有的EXTERNAL\u属性类型解析器只能处理字符串字段,不能处理对象。自动应答,因为我发现这很难理解。使用自定义的AsPropertyType
{
timestamp: 0,
type: {
eventType: "Foo"
majorVersion: 1
minorVersion: 0
},
data: {
foo: "baz"
}
}
现有的
EXTERNAL\u属性
类型解析器只能处理字符串字段,不能处理对象。自动应答,因为我发现这很难理解。使用自定义的AsPropertyTypeDeserializer
。Kotlin通过自动注册密封的类子类型而不需要注释,并将未知类型处理作为额外的好处,从而简化了这一过程:
class Event(
override val timestamp: Long,
val type: EventType,
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type",
visible = true
)
@JsonTypeResolver(EventDataTypeResolverBuilder::class)
val data: EventData
)
class EventType(
val majorVersion: Int,
val minorVersion: Int,
val eventType: String
)
sealed class EventData {
data class Foo(
val foo: String
) : EventData()
data class Bar(
val bar: String
) : EventData()
object Unknown: EventData()
}
class EventDataTypeResolverBuilder : StdTypeResolverBuilder() {
override fun buildTypeDeserializer(
config: DeserializationConfig,
baseType: JavaType,
subtypes: MutableCollection<NamedType>,
): TypeDeserializer {
val idRes = idResolver(
config,
baseType,
subTypeValidator(config),
subtypes,
false,
true
)
return EventDataTypeDeserializer(
baseType,
idRes,
_typeProperty,
_typeIdVisible,
null
)
}
}
class EventDataTypeDeserializer : AsPropertyTypeDeserializer {
constructor(
bt: JavaType,
idRes: TypeIdResolver,
typePropertyName: String,
typeIdVisible: Boolean,
defaultImpl: JavaType?,
) : super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl)
constructor(src: EventDataTypeDeserializer, property: BeanProperty) : super(src, property)
override fun forProperty(prop: BeanProperty): TypeDeserializer {
return if (prop === _property) this else EventDataTypeDeserializer(this, prop)
}
@Throws(IOException::class)
override fun deserializeTypedFromObject(p: JsonParser, ctxt: DeserializationContext): Any? {
val type = p.parsingContext.parent.currentValue as EventType
val typeId = "EventData\$${type.eventType}"
return _findDeserializer(ctxt, typeId).deserialize(p, ctxt)
}
override fun _handleUnknownTypeId(ctxt: DeserializationContext, typeId: String): JavaType {
return _idResolver.typeFromId(ctxt, "EventData\$Unknown")
}
}
类事件(
覆盖val时间戳:长,
val类型:EventType,
@JsonTypeInfo(
use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property=“type”,
可见=真
)
@JsonTypeResolver(EventDataTypeResolverBuilder::类)
val数据:事件数据
)
类事件类型(
val majorVersion:Int,
val minorVersion:Int,
val eventType:String
)
密封类事件数据{
数据类Foo(
瓦尔福:字符串
):EventData()
数据类栏(
值栏:字符串
):EventData()
对象未知:EventData()
}
类EventDataTypeResolverBuilder:StdTypeResolverBuilder(){
重写buildTypeDeserializer(
配置:反序列化配置,
baseType:JavaType,
子类型:可变集合,
):类型反序列化器{
val idRes=idResolver(
配置,
基本类型,
子验证程序(配置),
亚型,
假,,
真的
)
返回EventDataTypeDeserializer(
基本类型,
伊德里斯,
_类型属性,
_typeIdVisible,
无效的
)
}
}
类EventDataTypeDeserializer:AsPropertyTypeDeserializer{
建造师(
bt:JavaType,
idRes:TypeIdResolver,
typePropertyName:字符串,
typeIdVisible:Boolean,
defaultImpl:JavaType?,
):super(bt、idRes、typePropertyName、typeIdVisible、defaultImpl)
构造函数(src:EventDataTypeDeserializer,属性:BeanProperty):super(src,属性)
重写fun-forProperty(prop:BeanProperty):类型反序列化器{
如果(prop===\u属性)此else EventDataTypeDeserializer(此,prop)返回
}
@抛出(IOException::类)
重写有趣的反序列化TypedFromObject(p:JsonParser,ctxt:DeserializationContext):有吗{
val type=p.parsingContext.parent.currentValue作为事件类型
val typeId=“EventData\${type.eventType}”
return\u findDeserializer(ctxt,typeId)。反序列化(p,ctxt)
}
重写fun\u handleUnknownTypeId(ctxt:DeserializationContext,typeId:String):JavaType{
返回_idResolver.typeFromId(ctxt,“EventData\$Unknown”)
}
}