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)