【问题标题】:Kotlin Serialization to JSON: How to ignore actual field typeKotlin 序列化为 JSON:如何忽略实际的字段类型
【发布时间】:2018-09-13 15:08:26
【问题描述】:

我是 Kotlin 的新手,甚至是 Kotlin Serialization 的新手,我正在尝试将 Kotlin 数据类转换为 JSON。看下面的示例代码:

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JSON

fun main(args: Array<String>) {
    println(JSON.stringify(BaseClass1("abc")))
    println(JSON.stringify(BaseClass2("abc")))
}

@Serializable
data class BaseClass1(
        val a: String
)

@Serializable
data class BaseClass2(
        val a: Any
)

输出是:

{"a":"abc"}
{"a":["kotlin.String","abc"]}

所以我将字符串保存在Any 类型的变量中(这应该是完全有效的)。但是,这导致序列化的值是类型和值的数组。其他类和子类也会发生这种情况(例如,当我扩展字段的类型时)。

无论字段的实际类型如何,如何让stringify 始终使用该值?我希望上面程序的第二个stringify 结果与第一个匹配。

【问题讨论】:

    标签: json serialization kotlin


    【解决方案1】:

    我设法使用自定义序列化程序来完成此操作。

    唯一的缺点是因为我不保存类型,所以我不能再次反序列化对象,但我只需要在我的程序中进行序列化。

    @Serializable
    data class BaseClass2(
            @Serializable(with = PlainObjectSerializer::class) val a: Any
    )
    
    
    object PlainObjectSerializer : KSerializer<Any> {
        override val serialClassDesc: KSerialClassDesc
            get() = SerialClassDescImpl("") //PlainObjectDesc
    
        override fun save(output: KOutput, obj: Any) {
            val saver = serializerByValue(obj, output.context)
            output.writeSerializableValue(saver, obj)
        }
    
        override fun load(input: KInput): Any {
            throw Exception("This serializer can only be used for serialization!")
        }
    }
    

    编辑:作为@Nikkysuggested,可以通过使用序列化插件进一步简化此代码:

    @Serializer(forClass = BaseClass2::class)
    object PlainObjectSerializer : KSerializer<Any> {
        override fun save(output: KOutput, obj: Any) {
            val saver = serializerByValue(obj, output.context)
            output.writeSerializableValue(saver, obj)
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以通过使用@Serializer(forClass=BaseClass1:class) 注释序列化程序来简化您的解决方案 那么你可以省略负载和serialClassDesc覆盖..插件将为你生成默认值

      【讨论】:

      • 谢谢,这为我节省了一些杂乱的代码。但我建议您不要将其写成一个完整的答案,而是对我的答案发表评论,因为它只是补充信息。
      • 当时我处于所需的业力之下,可以在任何不是我的解决方案下发布答案,有点倒退,我不确定如果我现在删除我的答案会发生什么......所以我不会尝试
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多