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

如何使用Kotlin serialization兼容解析String或String数组类型字段

实现方案

1. 自定义兼容型反序列化器

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonPrimitive

object StringOrStringListSerializer : KSerializer<List<String>> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("StringOrStringList", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): List<String> {
        val jsonInput = decoder as JsonDecoder
        return when (val element = jsonInput.decodeJsonElement()) {
            // 单个String场景,自动包装为单元素List
            is JsonPrimitive -> listOf(element.content)
            // 数组场景,直接遍历取值
            is JsonArray -> element.map { it.jsonPrimitive.content }
            else -> error("不支持的Person字段类型:${element::class.simpleName}")
        }
    }

    // 若需要序列化回JSON可保留以下实现,不需要可以空实现
    override fun serialize(encoder: Encoder, value: List<String>) {
        encoder.encodeSerializableValue(JsonArray.serializer(), value.map { JsonPrimitive(it) })
    }
}

2. 给目标字段绑定反序列化器

统一用List<String>类型接收Person字段,通过注解指定自定义序列化器即可:

import kotlinx.serialization.Serializable

@Serializable
data class 你的接口返回实体类(
    @Serializable(with = StringOrStringListSerializer::class)
    val Person: List<String>,
    // 其他业务字段...
)

3. (可选)全局注册复用

如果项目中存在多个同类型的兼容字段,可以直接给Json实例全局注册序列化器,不需要每个字段都加注解:

import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule

val jsonParser = Json {
    ignoreUnknownKeys = true // 常规配置,忽略未知字段避免解析报错,可按需开启
    serializersModule = SerializersModule {
        contextual(StringOrStringListSerializer::class)
    }
}
// 后续所有接口解析都使用这个jsonParser实例即可

解析后不管服务端返回的是单个字符串还是字符串数组,你都可以直接通过List类型统一处理,不需要额外做类型判断


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:45:02