使用 Kotlinx.serialization 将 JSON 数组解析为 Map<String, String>
Posted
技术标签:
【中文标题】使用 Kotlinx.serialization 将 JSON 数组解析为 Map<String, String>【英文标题】:Parse a JSON array into Map<String, String> using Kotlinx.serialization 【发布时间】:2019-09-04 14:59:53 【问题描述】:我正在编写一个 Kotlin 多平台项目 (JVM/JS),我正在尝试使用 Kotlinx.serialization 将 HTTP Json 数组响应解析为 Map
JSON 是这样的:
["someKey": "someValue", "otherKey": "otherValue", "anotherKey": "randomText"]
到目前为止,我能够将 JSON 作为字符串获取,但我找不到任何文档来帮助我构建地图或其他类型的对象。所有这些都说明了如何序列化静态对象。
我不能使用@SerialName
,因为密钥不固定。
当我尝试返回 Map<String, String>
时,我收到此错误:
Can't locate argument-less serializer for class kotlin.collections.Map. For generic classes, such as lists, please provide serializer explicitly.
最后,我想获得Map<String, String>
或List<MyObject>
,我的对象可能是MyObject(val id: String, val value: String)
有没有办法做到这一点? 否则我只想写一个字符串阅读器来解析我的数据。
【问题讨论】:
是否有可能在 json 中得到重复的键? 所有键都是唯一的,值可以重复 如果有机会重构您的 json,请尝试将所有对象放在一个对象中,例如"someKey": "someValue", "otherKey": "otherValue"
,这是一种更好的数据结构
不,我正在写客户端。服务器正在返回它,我无权访问它。
github.com/Kotlin/kotlinx.serialization/blob/master/docs/…
【参考方案1】:
您可以像这样实现自己的简单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")
【讨论】:
完美运行!!我正在研究的解决方法是使用 expect class 解析器并在 jvm 中使用 klaxon(我完成了)和在 js 中使用 JSON.parse 编写这两种实现,但这涵盖了这两种情况。谢谢! 嘿伙计,SerialClassDescImpl("JsonMap")
做得怎么样?我也有定义吗?以上是关于使用 Kotlinx.serialization 将 JSON 数组解析为 Map<String, String>的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 kotlinx.serialization 部分解码 JSON 字符串?
Ktor 与 Kmongo 和 kotlinx.serialization
使用 kotlinx.serialization 在 ktor 服务器中接收 Map
在 Kotlin/Native 中使用 kotlinx.serialization 进行多态反序列化