如何将含递增键作为ID的JSON字符串映射到Kotlin数据类
问题原因
你的JSON结构是顶级对象直接包含数字字符串键对应的Item对象,但你定义的DataClassWithKeys期望JSON有一个名为items的顶级键,内部才是Map结构——这种结构不匹配导致解析器找不到对应键,从而报错。
解决方案
方法一:直接解析为Map(推荐)
不需要外层数据类,直接将JSON解析成Map<Int, Item>,Kotlinx Serialization原生支持这种结构的映射:
@Serializable data class Item( val title: Int, val artist: String, val album: String ) // 直接解析JSON为Map val itemMap = Json.decodeFromString<Map<Int, Item>>(jsonString)
解析时,JSON中的字符串键(如"0"、"1")会自动转换为Int类型,对应的值会被解析为Item对象。
方法二:保留外层数据类(自定义适配)
如果必须使用外层数据类,可以通过自定义序列化器,将JSON的顶级键映射到items字段:
import kotlinx.serialization.* import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.serializer @Serializable data class DataClassWithKeys( @Serializable(with = TopLevelMapSerializer::class) val items: Map<Int, Item> ) { @Serializable data class Item( val title: Int, val artist: String, val album: String ) // 自定义序列化器:将JSON顶级键值对直接映射为Map object TopLevelMapSerializer : KSerializer<Map<Int, Item>> { private val delegate = MapSerializer(Int.serializer(), Item.serializer()) override val descriptor: SerialDescriptor = delegate.descriptor override fun serialize(encoder: Encoder, value: Map<Int, Item>) { delegate.serialize(encoder, value) } override fun deserialize(decoder: Decoder): Map<Int, Item> { return delegate.deserialize(decoder) } } } // 解析调用 val dataClassWithMap = Json.decodeFromString<DataClassWithKeys>(jsonString)
内容的提问来源于stack exchange,提问作者jake wong
相关产品推荐
相关产品推荐

