将Kotlin嵌套类序列化为平面JSON [英] Serialize Kotlin nested classes to flat JSON

查看:81
本文介绍了将Kotlin嵌套类序列化为平面JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

一个例子:

  @Serializable数据类地址(val street:字符串,val postalCode:字符串)@可序列化数据类Customer(val id:字符串,val名称:字符串,val地址:地址) 

序列化时的默认行为是:

  {"id":"123ABC",名称":"Joe"地址":{街道":我的街道","postalCode":"123456"}} 

我想要的是:

  {"id":"123ABC",名称":"Joe"街道":我的街道","postalCode":"123456"} 

我无法在解决方案

可以使用 import kotlinx.serialization.descriptors.SerialDescriptor导入kotlinx.serialization.encoding.Decoder导入kotlinx.serialization.encoding.Encoder导入kotlinx.serialization.json.*导入kotlinx.serialization.*@可序列化数据类地址(val street:字符串,val postalCode:字符串)@Serializable(with = CustomerSerializer :: class)数据类Customer(val id:字符串,val名称:字符串,val地址:地址)@可序列化@SerialName(客户")私有数据类CustomerSurrogate(val id:字符串,val名称:字符串,val街道:字符串,val postalCode:字符串)对象CustomerSerializer:KSerializer< Customer>{覆盖val描述符:SerialDescriptor = CustomerSurrogate.serializer().descriptor覆盖乐趣反序列化(解码器:解码器):客户{val代理=解码器.decodeSerializableValue(CustomerSurrogate.serializer())返回客户(surrogate.id,surrogate.name,地址(surrogate.street,surrogate.postalCode))}覆盖有趣的序列化(编码器:编码器,值:客户){val surrogate = CustomerSurrogate(value.id,value.name,value.address.street,value.address.postalCode)encoder.encodeSerializableValue(CustomerSurrogate.serializer(),代理)}}有趣的main(){println(Json.encodeToString(Customer("123ABC","Joe",Address("my street","123456")))))}

I'm looking for a standardized way to serialize a Kotlin object into a "flat" Json with only key -> value pairs using kotlinx.serialization on the JVM.

An Example:

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

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

The default behaviour upon serialization is:

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

What i want is:

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

I could not find a way to accomplish this in the Kotlin Serialization Guide. Therefore I'm quite sure I have to implement a custom KSerializer<Customer> but currently don't see how to achieve to behaviour.

解决方案

This could be done with surrogate serializer technique:

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"))))
}

这篇关于将Kotlin嵌套类序列化为平面JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆