【问题标题】:Serialize Kotlin nested classes to flat JSON将 Kotlin 嵌套类序列化为平面 JSON
【发布时间】:2020-10-27 14:35:09
【问题描述】:

我正在寻找一种标准化方法,在 JVM 上使用 kotlinx.serialization 将 Kotlin 对象序列化为只有键 -> 值对的“平面”Json。

一个例子:

@Serializable
data class Address(val street: String, val postalCode: String)

@Serializable
data class Customer(val id: String, val name: String, val address: Address)

序列化时的默认行为是:

{
    "id": "123ABC",
    "name": "Joe"
    "address": {
        "street": "my street",
        "postalCode": "123456"
    }
}

我想要的是:

{
    "id": "123ABC",
    "name": "Joe"
    "street": "my street",
    "postalCode": "123456"
}

我在Kotlin Serialization Guide 中找不到实现此目的的方法。因此,我很确定我必须实现自定义 KSerializer<Customer>,但目前不知道如何实现行为。

【问题讨论】:

    标签: json kotlin serialization


    【解决方案1】:

    这可以通过surrogate serializer 技术完成:

    import kotlinx.serialization.descriptors.SerialDescriptor
    import kotlinx.serialization.encoding.Decoder
    import kotlinx.serialization.encoding.Encoder
    import kotlinx.serialization.json.*
    import kotlinx.serialization.*
    
    @Serializable
    data class Address(val street: String, val postalCode: String)
    
    @Serializable(with = CustomerSerializer::class)
    data class Customer(val id: String, val name: String, val address: Address)
    
    @Serializable
    @SerialName("Customer")
    private data class CustomerSurrogate(val id: String, val name: String, val street: String, val postalCode: String)
    
    object CustomerSerializer : KSerializer<Customer> {
        override val descriptor: SerialDescriptor = CustomerSurrogate.serializer().descriptor
        override fun deserialize(decoder: Decoder): Customer {
            val surrogate = decoder.decodeSerializableValue(CustomerSurrogate.serializer())
            return Customer(surrogate.id, surrogate.name, Address(surrogate.street, surrogate.postalCode))
        }
    
        override fun serialize(encoder: Encoder, value: Customer) {
            val surrogate = CustomerSurrogate(value.id, value.name, value.address.street, value.address.postalCode)
            encoder.encodeSerializableValue(CustomerSurrogate.serializer(), surrogate)
        }
    }
    
    fun main() {
        println(Json.encodeToString(Customer("123ABC", "Joe", Address("my street", "123456"))))
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 2011-08-05
      • 2021-03-02
      相关资源
      最近更新 更多