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

如何将Kotlin的NullableStringSerializer改造为通用序列化器?

解决方案

方法一:全局配置解码转换器(最简便)

无需编写自定义序列化器,直接在Json配置中添加全局解码转换器,将所有空字符串的JSON元素转为JsonNull,可空类型会自动解析为null:

val json = Json {
    decodeTransformers += JsonTransformer { element ->
        if (element is JsonPrimitive && element.isString && element.content.isEmpty()) {
            JsonNull
        } else {
            element
        }
    }
}

之后使用标准可空类型数据类即可,无需额外注解:

@Serializable
data class Foo(val bar: Long?)

方法二:通用泛型序列化器(按需绑定)

如果仅需对特定字段生效,可编写通用泛型序列化器,配合工厂函数和委托object实现:

  1. 定义通用序列化器类
class NullableStringToNullSerializer<T>(private val delegate: KSerializer<T>) : KSerializer<T?> {
    override val descriptor: SerialDescriptor = delegate.descriptor.nullable

    override fun serialize(encoder: Encoder, value: T?) {
        value?.let(delegate::serialize) ?: encoder.encodeNull()
    }

    override fun deserialize(decoder: Decoder): T? {
        val element = decoder.decodeJsonElement()
        return if (element is JsonPrimitive && element.isString && element.content.isEmpty()) {
            null
        } else {
            delegate.deserialize(JsonDecoder(decoder.json, element))
        }
    }

    companion object {
        inline fun <reified T> create(): KSerializer<T?> = NullableStringToNullSerializer(serializer())
    }
}
  1. 为需要的类型创建委托object(仅需一行代码)
object LongNullableStringSerializer : KSerializer<Long?> by NullableStringToNullSerializer.create<Long>()
object IntNullableStringSerializer : KSerializer<Int?> by NullableStringToNullSerializer.create<Int>()
  1. 在数据类中使用
@Serializable
data class Foo(@Serializable(with = LongNullableStringSerializer::class) val bar: Long?)

方法三:泛型JsonTransformingSerializer配合工厂函数

利用JsonTransformingSerializer特性,结合reified类型参数的工厂函数:

class GenericNullableStringSerializer<T>(serializer: KSerializer<T>) : JsonTransformingSerializer<T>(serializer) {
    override fun transformDeserialize(element: JsonElement): JsonElement =
        if (element is JsonPrimitive && element.isString && element.content.isEmpty()) JsonNull else element

    companion object {
        inline fun <reified T> create(): KSerializer<T> = GenericNullableStringSerializer(serializer())
    }
}

使用时通过委托object间接引用(注解无法直接使用函数返回值):

object LongNullableTransformer : KSerializer<Long?> by GenericNullableStringSerializer.create<Long?>()

@Serializable
data class Foo(@Serializable(with = LongNullableTransformer::class) val bar: Long?)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:24:39