解析异构数据数组的正确方法:处理JSON解析时字段类型不统一问题
解决方案
你可以通过自定义Gson反序列化器兼容单字符串和字符串数组两种格式,有两种实现方式可选:
方式1:字段单独生效(更推荐,不影响全局解析规则)
首先实现自定义反序列化器:
import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement import java.lang.reflect.Type class StringListDeserializer : JsonDeserializer<List<String>> { override fun deserialize( json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext? ): List<String> { return when { // 匹配数组类型,遍历转为字符串列表 json?.isJsonArray == true -> json.asJsonArray.map { it.asString } // 匹配单个字符串类型,包装为单元素列表 json?.isJsonPrimitive == true && json.asJsonPrimitive.isString -> listOf(json.asString) // 空值/不匹配类型返回空列表,可根据业务需求调整为返回null或抛出异常 else -> emptyList() } } }
然后直接在你的模型类的value字段上添加@JsonAdapter注解即可:
class CFInsertedValuesStructure { @SerializedName("id") val id : Int? = null @SerializedName("value") @JsonAdapter(StringListDeserializer::class) val value : List<String> = listOf() @SerializedName("field_id") val field_id : String? = null }
方式2:全局生效
如果你希望所有List<String>类型的字段都自动兼容单值和数组格式,可以在构建Gson实例时注册该反序列化器:
import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken val gson = GsonBuilder() .registerTypeAdapter(object : TypeToken<List<String>>() {}.type, StringListDeserializer()) .create()
这种方式不需要修改模型类的字段注解,全局所有List<String>字段都会应用该解析规则。
内容的提问来源于stack exchange,提问作者Federico Malagoni
相关产品推荐
相关产品推荐

