如何使用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
相关产品推荐
相关产品推荐

