如何使用Moshi处理含重复字段的JSON数据?
解决Moshi解析重复JSON字段报错的方案
当使用Moshi解析包含重复字段的JSON时,会触发如下错误:
com.squareup.moshi.JsonDataException: Multiple values for 'name' at $.person.name
触发该错误的典型JSON格式示例:
{ "name" : "Chuck", "age" : 21, "name" : "Chuck" }
已知背景
Moshi官方目前不支持忽略或覆盖重复字段的功能,官方认为这类问题属于API设计层面的缺陷,而非库本身需要解决的问题。此前已有方案将重复字段合并为列表,但如果需要直接忽略重复字段(保留第一个值)或覆盖重复字段(保留最后一个值),可以通过自定义Moshi适配器实现。
方案1:保留最后一个重复字段(覆盖前面的值)
通过自定义适配器,在解析时每次遇到重复字段都覆盖之前的值,最终保留最后出现的字段值。
首先定义实体类:
data class Person(val name: String, val age: Int)
编写自定义适配器:
class PersonAdapter { @FromJson fun fromJson(reader: JsonReader): Person { var name: String? = null var age: Int? = null reader.beginObject() while (reader.hasNext()) { when (reader.nextName()) { "name" -> name = reader.nextString() // 重复字段直接覆盖,保留最后一个值 "age" -> age = reader.nextInt() else -> reader.skipValue() // 跳过未知字段 } } reader.endObject() return Person(name ?: "", age ?: 0) // 根据业务需求处理空值情况 } }
注册适配器到Moshi并使用:
val moshi = Moshi.Builder() .add(PersonAdapter()) .build() val personAdapter = moshi.adapter(Person::class.java) val targetPerson = personAdapter.fromJson(yourJsonString)
方案2:保留第一个重复字段(忽略后续重复值)
修改适配器逻辑,仅在字段未赋值时读取,后续重复字段直接跳过。
自定义适配器代码:
class PersonAdapter { @FromJson fun fromJson(reader: JsonReader): Person { var name: String? = null var age: Int? = null reader.beginObject() while (reader.hasNext()) { val fieldName = reader.nextName() when (fieldName) { "name" -> { if (name == null) { // 仅读取第一个出现的字段值 name = reader.nextString() } else { reader.skipValue() // 跳过后续重复字段 } } "age" -> age = reader.nextInt() else -> reader.skipValue() } } reader.endObject() return Person(name ?: "", age ?: 0) } }
注册和使用方式与方案1一致。
内容的提问来源于stack exchange,提问作者LethalMaus
相关产品推荐
相关产品推荐

