0

假设我有以下 json 对象:

{
    "type": "video",
    "...": "..."
}
{
    "type": "image",
    "...": "..."
}

它们都代表媒体对象。Kotlin 密封模型如下所示:

sealed class Media {
    ...
}

@Serializable
@SerialName("video")
data class Video(...) : Media()

@Serializable
@SerialName("image")
data class Image(...) : Media()

根据 KoltinX doc,我使用了一个包装器进行多态序列化:

@Serializable
private data class MediaWrapper(@Polymorphic val media: Media) {
    companion object {
        val jsonSerializer = Json(
            context = SerializersModule {
                polymorphic<Media> {
                    Video::class with Video.serializer()
                    Image::class with Image.serializer()
                }
            }
        )

        fun fromJson(json: String) = jsonSerializer.parse(serializer(), json)
    }
}

目标是Media使用我的包装器反序列化 json,但问题是我需要将我Media的 json 更改为MediaWrapperjson。我发现最方便的解决方案是在我的json的每一侧添加{\"media\":\"& :\"}Media

sealed class Media {
    companion object {
        fun fromJson(mediaJson: String): Media {
            val mediaWrapperJson = "{\"media\":$mediaJson}"
            val mediaWrapper = MediaWrapper.fromJson(mediaWrapperJson)
            return mediaWrapper.media
        }
    }
}

这是一个技巧,如果有更方便的反序列化多态的方法,请告诉我!

4

1 回答 1

3

虽然 kotlinx 序列化文档在其许多多态示例中使用了包装器,但它并没有说这种模式是强制性的。

从文档:

专业提示:要在没有包装器的情况下使用 Message,您可以传递 PolymorphicSerializer(Message::class) 来解析/字符串化。

在你的情况下,你可以这样做:

sealed class Media {
    companion object {
        val jsonSerializer = Json(
            context = SerializersModule {
                polymorphic<Media> {
                    Video::class with Video.serializer()
                    Image::class with Image.serializer()
                }
            }
        )

        fun fromJson(mediaJson: String): Media {
           return jsonSerializer.parse(PolymorphicSerializer(Media::class), mediaJson) as Media
        }
    }
}
于 2019-09-06T20:10:38.150 回答