Kotlin中嵌套列表对象的多态反序列化
Polymorphic deserialization of nested list object in Kotlin
尝试反序列化一个非常复杂的 json 字符串,我已经完成了一些更简单的操作,但我正在努力解决如何设置它的问题。我还找到了一些关于简单多态反序列化的示例,但无法弄清楚如何使其适应这种更复杂的情况,在这种情况下,我有不同的嵌套对象,其中一些是多态的,而另一些则不是。任何帮助将不胜感激!
@Serializalbe
data class Object1(
@SerialName("id")
val id: String,
@SerialName("object2"),
val object2: List<Object2>
)
data class Object2(
@SerialName("name")
val name: String,
@SerialName("object2"),
val object3: List<Object3>
)
@Polymorphic
interface Object3: Parcelable {
val id: String
/**
* [Object3.Item1],
* [Object3.Item2]
*/
val type: Object3.Type
val data: Data
val options: List<Options>
}
@Serializable
@SerialName(type)
@Parcelize
data class Item1(
@SerialName("_version")
val version: String,
@SerialName("info")
override val info: AnotherPolyMorphicItem,
) : Object3 {
override val type: Type get() = Object3.Type.Item1
}
@Serializable
@SerialName(type)
@Parcelize
data class Item2(
@SerialName("_title")
val tile: String,
@SerialName("info")
val info: AnotherPolymorphicItem,
@SerialName("post")
val post: String
) : Object3 {
override val type: Type get() = Object3.Type.Item2
}
我为 Object3 反序列化构建了这个:
object Object3Json : SerializerContainer {
override val serializer =
Json {
isLenient = false
ignoreUnknownKeys = false
allowSpecialFloatingPointValues = true
useArrayPolymorphism = false
ignoreUnknownKeys = true
useAlternativeNames = false
classDiscriminator = "type"
serializersModule = SerializersModule {
polymorphic(Object3::class) {
subclass(Item1::class, Item1.serializer())
}
polymorphic(Object3::class) {
subclass(Item2::class, Item2.serializer())
}
}
}
}
我也一直在反序列化更简单的 json 字符串,如下所示:
object DefaultJson : SerializerContainer {
override val serializer: Json by lazy {
Json {
isLenient = false
useAlternativeNames = false
}
}
}
val responseObject = DefaultJson.serializer.decodeFromString(
ResponseObject.serializer(), payload
)
@Serializable
data class ResponseObject(
@SerialName("data1")
val data1: String,
@SerialName("data2")
val data2: String
)
我的问题是如何将更简单的反序列化与多态性结合起来,以及如何反序列化为对象列表,就像我想反序列化 Object1 的列表一样,我已经按照我发现的示例抛出错误.
我们的项目有一些多态序列化,但我不知道你是否认为它很复杂。我们已经通过 @JsonTypeInfo
/@JsonSubTypes
注释的仔细提示实现了标准 Jackson 的所有序列化。
这是一个代码片段 - 通过在 class 中使用类型指示符,我们已经实现了 round-trip 序列化,而无需任何自定义序列化程序。在这种情况下,我们有 6 种类型的事件,它们使用 3 个具体 classes 之一(一些细节,如接口,为简洁起见省略了所有 class 字段):
enum class EventType(val eventClass: KClass<out Event>) {
CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_CLINICIAN(MemberClinicianMessageEvent::class),
CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_MEMBER(MemberClinicianMessageEvent::class),
MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MENTOR(MentorMemberMessageEvent::class),
MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MEMBER(MentorMemberMessageEvent::class),
CARD_ACTION_TO_MEMBER(CardActionEvent::class),
CARD_ACTION_TO_CLINICIAN(CardActionEvent::class),
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "eventType",
visible = true
)
@JsonSubTypes(
JsonSubTypes.Type(name = "CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_CLINICIAN", value = MemberClinicianMessageEvent::class),
JsonSubTypes.Type(name = "CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_MEMBER", value = MemberClinicianMessageEvent::class),
JsonSubTypes.Type(name = "MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MENTOR", value = MentorMemberMessageEvent::class),
JsonSubTypes.Type(name = "MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MEMBER", value = MentorMemberMessageEvent::class),
JsonSubTypes.Type(name = "CARD_ACTION_TO_MEMBER", value = CardActionEvent::class),
JsonSubTypes.Type(name = "CARD_ACTION_TO_CLINICIAN", value = CardActionEvent::class),
)
data class MemberClinicianMessageEvent(
override val id: RULID,
override val eventType: EventType,
override val createdBy: SkinnyProfile,
...skip...
) : StackEvent
data class MentorMemberMessageEvent(
override val id: RULID,
override val eventType: EventType,
override val createdBy: SkinnyProfile,
...skip...
) : StackEvent
data class CardActionEvent(
override val id: RULID,
override val eventType: EventType,
override val createdBy: SkinnyProfile,
...skip...
) : StackEvent
eventClass
在第一个枚举中不需要序列化,但允许我们在其他地方执行类型验证。
所以这比我想象的要简单得多。它 returns 看起来有点滑稽,直到你进入多态 class 但所有数据都可以使用我设置的数据 class 结构访问。
我创建了 dataClass
来保存 Object1
的列表,然后稍微调整了响应以包含它,所以我现在有:
@Serializable
data class Object1List(
@SerialName("object1")
val object1: List<Object1>
)
然后我反序列化如下,有效载荷是我反序列化的 JSON 字符串。
val response = Object3Json.serializer.decodeFromString(Object1List.serializer(), payload)
尝试反序列化一个非常复杂的 json 字符串,我已经完成了一些更简单的操作,但我正在努力解决如何设置它的问题。我还找到了一些关于简单多态反序列化的示例,但无法弄清楚如何使其适应这种更复杂的情况,在这种情况下,我有不同的嵌套对象,其中一些是多态的,而另一些则不是。任何帮助将不胜感激!
@Serializalbe
data class Object1(
@SerialName("id")
val id: String,
@SerialName("object2"),
val object2: List<Object2>
)
data class Object2(
@SerialName("name")
val name: String,
@SerialName("object2"),
val object3: List<Object3>
)
@Polymorphic
interface Object3: Parcelable {
val id: String
/**
* [Object3.Item1],
* [Object3.Item2]
*/
val type: Object3.Type
val data: Data
val options: List<Options>
}
@Serializable
@SerialName(type)
@Parcelize
data class Item1(
@SerialName("_version")
val version: String,
@SerialName("info")
override val info: AnotherPolyMorphicItem,
) : Object3 {
override val type: Type get() = Object3.Type.Item1
}
@Serializable
@SerialName(type)
@Parcelize
data class Item2(
@SerialName("_title")
val tile: String,
@SerialName("info")
val info: AnotherPolymorphicItem,
@SerialName("post")
val post: String
) : Object3 {
override val type: Type get() = Object3.Type.Item2
}
我为 Object3 反序列化构建了这个:
object Object3Json : SerializerContainer {
override val serializer =
Json {
isLenient = false
ignoreUnknownKeys = false
allowSpecialFloatingPointValues = true
useArrayPolymorphism = false
ignoreUnknownKeys = true
useAlternativeNames = false
classDiscriminator = "type"
serializersModule = SerializersModule {
polymorphic(Object3::class) {
subclass(Item1::class, Item1.serializer())
}
polymorphic(Object3::class) {
subclass(Item2::class, Item2.serializer())
}
}
}
}
我也一直在反序列化更简单的 json 字符串,如下所示:
object DefaultJson : SerializerContainer {
override val serializer: Json by lazy {
Json {
isLenient = false
useAlternativeNames = false
}
}
}
val responseObject = DefaultJson.serializer.decodeFromString(
ResponseObject.serializer(), payload
)
@Serializable
data class ResponseObject(
@SerialName("data1")
val data1: String,
@SerialName("data2")
val data2: String
)
我的问题是如何将更简单的反序列化与多态性结合起来,以及如何反序列化为对象列表,就像我想反序列化 Object1 的列表一样,我已经按照我发现的示例抛出错误.
我们的项目有一些多态序列化,但我不知道你是否认为它很复杂。我们已经通过 @JsonTypeInfo
/@JsonSubTypes
注释的仔细提示实现了标准 Jackson 的所有序列化。
这是一个代码片段 - 通过在 class 中使用类型指示符,我们已经实现了 round-trip 序列化,而无需任何自定义序列化程序。在这种情况下,我们有 6 种类型的事件,它们使用 3 个具体 classes 之一(一些细节,如接口,为简洁起见省略了所有 class 字段):
enum class EventType(val eventClass: KClass<out Event>) {
CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_CLINICIAN(MemberClinicianMessageEvent::class),
CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_MEMBER(MemberClinicianMessageEvent::class),
MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MENTOR(MentorMemberMessageEvent::class),
MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MEMBER(MentorMemberMessageEvent::class),
CARD_ACTION_TO_MEMBER(CardActionEvent::class),
CARD_ACTION_TO_CLINICIAN(CardActionEvent::class),
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "eventType",
visible = true
)
@JsonSubTypes(
JsonSubTypes.Type(name = "CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_CLINICIAN", value = MemberClinicianMessageEvent::class),
JsonSubTypes.Type(name = "CLINICIAN_MEMBER_CHANNEL_MESSAGE_TO_MEMBER", value = MemberClinicianMessageEvent::class),
JsonSubTypes.Type(name = "MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MENTOR", value = MentorMemberMessageEvent::class),
JsonSubTypes.Type(name = "MENTOR_MEMBER_CHANNEL_MESSAGE_TO_MEMBER", value = MentorMemberMessageEvent::class),
JsonSubTypes.Type(name = "CARD_ACTION_TO_MEMBER", value = CardActionEvent::class),
JsonSubTypes.Type(name = "CARD_ACTION_TO_CLINICIAN", value = CardActionEvent::class),
)
data class MemberClinicianMessageEvent(
override val id: RULID,
override val eventType: EventType,
override val createdBy: SkinnyProfile,
...skip...
) : StackEvent
data class MentorMemberMessageEvent(
override val id: RULID,
override val eventType: EventType,
override val createdBy: SkinnyProfile,
...skip...
) : StackEvent
data class CardActionEvent(
override val id: RULID,
override val eventType: EventType,
override val createdBy: SkinnyProfile,
...skip...
) : StackEvent
eventClass
在第一个枚举中不需要序列化,但允许我们在其他地方执行类型验证。
所以这比我想象的要简单得多。它 returns 看起来有点滑稽,直到你进入多态 class 但所有数据都可以使用我设置的数据 class 结构访问。
我创建了 dataClass
来保存 Object1
的列表,然后稍微调整了响应以包含它,所以我现在有:
@Serializable
data class Object1List(
@SerialName("object1")
val object1: List<Object1>
)
然后我反序列化如下,有效载荷是我反序列化的 JSON 字符串。
val response = Object3Json.serializer.decodeFromString(Object1List.serializer(), payload)