You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用kotlinx将指定JSON反序列化为带序列化名的POJO?

解决方案:自定义序列化器实现原始值到Slot的转换

你的需求是将JSON中的原始值字段直接反序列化为包含字段名(序列化名称)和对应值的Slot对象,核心问题是默认序列化逻辑期望JSON字段结构与Slot类匹配,但实际输入是原始值,因此需要自定义序列化器完成转换。

步骤1:修正基础类定义

先修正Slot和Slots的类型(Kotlin中使用Int而非Integer):

@Serializable
class Slot<T>(val name: String, val value: T)

@Serializable
class Slots(
    @SerialName("a")
    val propertyA: Slot<Int>? = null,
    @SerialName("b")
    val propertyB: Slot<String>? = null,
    @SerialName("c")
    val propertyC: Slot<Boolean>? = null
)

步骤2:编写通用Slot序列化器

创建抽象通用序列化器,接收目标字段名和值类型序列化器,实现原始值与Slot对象的双向转换:

abstract class SlotSerializer<T>(
    private val fieldName: String,
    private val valueSerializer: KSerializer<T>
) : KSerializer<Slot<T>> {
    // 描述符与原始值类型保持一致,确保序列化/反序列化兼容原始JSON结构
    override val descriptor: SerialDescriptor = valueSerializer.descriptor

    // 序列化时,只输出Slot的value值(还原为原始JSON结构)
    override fun serialize(encoder: Encoder, value: Slot<T>) {
        valueSerializer.serialize(encoder, value.value)
    }

    // 反序列化时,读取原始值并包装为Slot,自动填充字段名
    override fun deserialize(decoder: Decoder): Slot<T> {
        val rawValue = valueSerializer.deserialize(decoder)
        return Slot(fieldName, rawValue)
    }
}

步骤3:为每个字段创建专属序列化器

针对Slots中的每个属性,创建对应字段名的具体序列化器:

// 对应"a"字段,值类型为Int
class SlotASerializer : SlotSerializer<Int>("a", Int.serializer())
// 对应"b"字段,值类型为String
class SlotBSerializer : SlotSerializer<String>("b", String.serializer())
// 对应"c"字段,值类型为Boolean
class SlotCSerializer : SlotSerializer<Boolean>("c", Boolean.serializer())

步骤4:为Slots属性指定序列化器

在Slots类的每个属性上添加@Serializable(with = ...)注解,绑定对应的专属序列化器:

@Serializable
class Slots(
    @SerialName("a")
    @Serializable(with = SlotASerializer::class)
    val propertyA: Slot<Int>? = null,
    @SerialName("b")
    @Serializable(with = SlotBSerializer::class)
    val propertyB: Slot<String>? = null,
    @SerialName("c")
    @Serializable(with = SlotCSerializer::class)
    val propertyC: Slot<Boolean>? = null
)

测试验证

使用Json.decodeFromString进行反序列化测试:

fun main() {
    val json = """{"a": 123, "b": "foo", "c": false}"""
    val result = Json.decodeFromString<Slots>(json)
    println(result)
    // 输出:Slots(propertyA=Slot(name=a, value=123), propertyB=Slot(name=b, value=foo), propertyC=Slot(name=c, value=false))
}

该方案既能完成反序列化时的包装,也能保证序列化时将Slot对象还原为原始JSON字段结构,满足双向兼容需求。

内容的提问来源于stack exchange,提问作者Bakkenrak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:22:45