Kotlinx.serialization如何解析字符串与空对象两种返回值到指定数据类
你可以通过为String?类型自定义宽松反序列化器实现需求,核心逻辑是反序列化时如果遇到JSON对象类型直接返回null,遇到字符串类型就正常取值,具体实现步骤如下:
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.JsonObject import kotlinx.serialization.json.JsonPrimitive object LenientStringSerializer : KSerializer<String?> { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LenientString", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): String? { val jsonDecoder = decoder as JsonDecoder return when (val element = jsonDecoder.decodeJsonElement()) { // 匹配字符串类型,直接返回内容 is JsonPrimitive -> element.content // 匹配对象类型,直接返回null is JsonObject -> null // 其他不匹配类型也可按需返回null else -> null } } override fun serialize(encoder: Encoder, value: String?) { // 序列化逻辑按需实现,仅做反序列化可以简化处理 value?.let { encoder.encodeString(it) } ?: encoder.encodeNull() } }
2. 给目标字段绑定反序列化器
修改你的数据类,给x字段指定自定义的序列化器:
import kotlinx.serialization.Serializable import kotlinx.serialization.SerialName @Serializable data class SomeClass( @SerialName("x") @Serializable(with = LenientStringSerializer::class) val x: String? )
3. 可选配置Json解析实例
如果还有其他通用的宽松解析需求,可以在构造Json实例时开启相关配置:
val json = Json { ignoreUnknownKeys = true // 忽略未声明的字段,常规场景推荐开启 coerceInputValues = true // 类型不匹配时自动用属性默认值,无默认值返回null }
配置完成后即可兼容两种响应结构:
- 第一种
x为字符串的响应,解析后x取值为对应字符串内容 - 第二种
x为空对象的响应,解析后x取值为null
如果需要适配
x为数字、布尔等其他异常类型的场景,只需要在deserialize方法的when分支中补充对应类型的判断逻辑即可。
内容的提问来源于stack exchange,提问作者Michael Peters
相关产品推荐
相关产品推荐

