【问题标题】:Kotlin Serialization - Decoding JSON Array from stringKotlin 序列化 - 从字符串解码 JSON 数组
【发布时间】:2021-07-21 06:34:20
【问题描述】:

尝试将缓存的 json 字符串反序列化为数据对象并获得异常:kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject (Kotlin reflection is not available) as the serialized body of kotlinx.serialization.Polymorphic<List>, but had class kotlinx.serialization.json.JsonArray (Kotlin reflection is not available)

用于反序列化的代码

internal inline fun <reified R : Any> String.convertToDataClass() =
    Json {
        ignoreUnknownKeys = true
    }.decodeFromString(R::class.serializer(), this)

代码示例:

val jsonString  ="""
[{"name1":"value1"}, {"name2":"value2"}]
"""
val dataObject = jsonString.convertToDataClass<List<SomeObject>>()

通过 Ktor 管道时,一切正常,但尝试反序列化缓存为字符串的相同响应主体时,它会中断。

我知道R::class.serializer() 被标记为内部使用,但这是我知道的如何从字符串内容反序列化泛型的唯一方法。

【问题讨论】:

  • 我不确定这是否有效,但你能不能将R 用作decodeFromString 的通用参数?
  • 嗨@Dominik。如果您使用Json 类函数decodeFromString,则不能将R 作为参数传递。但是,您的问题导致我发现StringFormat 具有名称相同但定义不同的扩展功能,您可以将R 作为参数传递。切换到它,解决了错误。
  • 为什么不呢?你真的得到Json.decodeFromString&lt;R&gt;(this) 的编译器错误吗?
  • 是的,它需要两个参数。这是函数fun &lt;T&gt; decodeFromString(deserializer: DeserializationStrategy&lt;T&gt;, string: String): T的定义
  • 检查github.com/Kotlin/…。样本是val obj = Json.decodeFromString&lt;Project&gt;(string),所以应该有合适的过载。

标签: json kotlin serialization deserialization kotlin-multiplatform


【解决方案1】:

kotlinx.serialization.decodeFromString 提供了一个合适的扩展函数,它采用一个通用参数,因此您可以将 R 作为通用传递给该扩展。

检查https://github.com/Kotlin/kotlinx.serialization#introduction-and-references。示例是val obj = Json.decodeFromString&lt;Project&gt;(string),它将满足您执行此类操作的需求

import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json    

internal inline fun <reified R : Any> String.convertToDataClass() =
    Json {
        ignoreUnknownKeys = true
    }.decodeFromString<R>(this)

【讨论】:

  • 请在答案import kotlinx.serialization.decodeFromString 中添加导入语句。也许像我这样使用显式导入语句的人不知道扩展功能。
猜你喜欢
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2021-11-29
  • 2013-09-27
  • 2016-05-13
  • 1970-01-01
  • 2020-12-14
相关资源
最近更新 更多