Kotlinx Serialization解析JSON如何忽略未知枚举值并跳过非法对象
问题原因分析
ignoreUnknownKeys = true仅作用于JSON中存在、但数据类未定义的字段,无法处理枚举值不匹配的场景coerceInputValues = true仅对设置了默认值的字段生效,你未给enumValue1设置默认值,同时枚举类没有定义未知值的对应 fallback 条目,所以输入不匹配时不会触发默认值逻辑,直接抛出字段错误- 你提供的JSON外层结构是每个元素为单key对象(key为object/object2等),value才是目标Class数组,需要先适配外层结构的解析
实现方案
你可以任选以下两种方案实现需求:
方案1:启用coerceInputValues + 新增枚举 fallback,解析后过滤
首先修改枚举类和数据类,补充未知值对应条目和字段默认值:
@Serializable enum class EnumValue { @SerialName("value1") VALUE_1, @SerialName("value2") VALUE_2, UNKNOWN // 未匹配的输入会被强制转为该值 } @Serializable data class Class( @SerialName("enumValue1") val enumValue1: EnumValue = EnumValue.UNKNOWN, @SerialName("value2") val value2: Int )
配置序列化参数后解析,再过滤非法条目即可:
val json = Json { ignoreUnknownKeys = true coerceInputValues = true } // 先适配外层JSON结构解析,再拍平、过滤非法条目 val validList: List<Class> = json.decodeFromString<List<Map<String, List<Class>>>>(yourJsonStr) .flatMap { it.values.flatten() } .filter { it.enumValue1 != EnumValue.UNKNOWN }
方案2:自定义反序列化器,遇到非法枚举直接跳过
如果不想修改原有枚举定义,可以自定义反序列化器捕获异常,解析后过滤空值即可:
// 自定义安全反序列化器,不匹配的枚举值返回null object SafeEnumValueDeserializer : DeserializationStrategy<EnumValue?> { override val descriptor = EnumValue.serializer().descriptor override fun deserialize(decoder: Decoder): EnumValue? { return runCatching { EnumValue.serializer().deserialize(decoder) }.getOrNull() } } // 给字段指定自定义反序列化器,设默认值为null @Serializable data class Class( @SerialName("enumValue1") @Serializable(with = SafeEnumValueDeserializer::class) val enumValue1: EnumValue? = null, @SerialName("value2") val value2: Int )
解析后过滤即可得到合法对象:
val json = Json { ignoreUnknownKeys = true } val validList: List<Class> = json.decodeFromString<List<Map<String, List<Class>>>>(yourJsonStr) .flatMap { it.values.flatten() } .filter { it.enumValue1 != null }
内容的提问来源于stack exchange,提问作者JohnDoe
相关产品推荐
相关产品推荐

