7

我正在编写一个 Kotlin 多平台项目 (JVM/JS),我正在尝试使用 Kotlinx.serialization 将 HTTP Json 数组响应解析为 Map

JSON是这样的:

[{"someKey": "someValue"}, {"otherKey": "otherValue"}, {"anotherKey": "randomText"}]

到目前为止,我能够将该 JSON 作为字符串,但我找不到任何文档来帮助我构建地图或其他类型的对象。所有这些都说明了如何序列化静态对象。

我不能使用@SerialName,因为密钥不固定。

当我尝试返回 aMap<String, String>时,我收到此错误:

Can't locate argument-less serializer for class kotlin.collections.Map. For generic classes, such as lists, please provide serializer explicitly.

最后,我想得到 aMap<String, String>或 aList<MyObject>我的对象可能在的地方MyObject(val id: String, val value: String)

有没有办法做到这一点?否则我只想写一个字符串阅读器来解析我的数据。

4

1 回答 1

10

您可以像这样实现自己的简单DeserializationStrategy

object JsonArrayToStringMapDeserializer : DeserializationStrategy<Map<String, String>> {

    override val descriptor = SerialClassDescImpl("JsonMap")

    override fun deserialize(decoder: Decoder): Map<String, String> {

        val input = decoder as? JsonInput ?: throw SerializationException("Expected Json Input")
        val array = input.decodeJson() as? JsonArray ?: throw SerializationException("Expected JsonArray")

        return array.map {
            it as JsonObject
            val firstKey = it.keys.first()
            firstKey to it[firstKey]!!.content
        }.toMap()


    }

    override fun patch(decoder: Decoder, old: Map<String, String>): Map<String, String> =
        throw UpdateNotSupportedException("Update not supported")

}


fun main() {
    val map = Json.parse(JsonArrayToStringMapDeserializer, data)
    map.forEach { println("${it.key} - ${it.value}") }
}
于 2019-04-14T17:29:00.740 回答