Moshi中实现可选字段不存在时忽略、存在时正常解析的解决方案(含类型不匹配错误处理)
解决Moshi解析布尔/缺失字段到Int类型的问题
这个问题的核心是API返回的recommended字段存在类型不一致(有时是布尔值,有时缺失),而Moshi默认无法自动完成布尔值到Int的转换,同时还要处理字段缺失时的默认值逻辑。下面是针对你的需求的具体解决方案:
方案:自定义Moshi类型适配器
我们可以编写一个自定义适配器,专门处理布尔值到Int的转换,同时兼顾字段缺失的情况:
1. 实现自定义适配器
创建一个适配器类,负责将JSON中的布尔值(或Int值)转换为Int,字段缺失时返回默认值0:
class BooleanToIntAdapter { @FromJson fun fromJson(value: Any?): Int { return when (value) { // 布尔值转Int:true→1,false→0 is Boolean -> if (value) 1 else 0 // 本身就是Int的话直接返回 is Int -> value // 字段不存在(value为null)时返回默认值0 null -> 0 // 其他意外类型也返回默认值,避免崩溃 else -> 0 } } // 序列化时直接返回Int值(如果有需要序列化的场景) @ToJson fun toJson(value: Int): Int { return value } }
2. 在数据类字段上应用适配器
修改你的CatalogProduct数据类,在recommended字段上添加@JsonAdapter注解,指定我们刚写的适配器:
@Parcelize @JsonClass(generateAdapter = true) data class CatalogProduct( @Json(name = "recommended") @JsonAdapter(BooleanToIntAdapter::class) val recommended: Int = 0 ) : Parcelable
3. 确保Moshi配置正确
如果你是通过全局Moshi实例配置的,记得要添加Kotlin适配器工厂(你已经在依赖里引入了moshi-kotlin-codegen,kapt会自动处理,但全局构建时可以参考以下代码):
val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) // 如果没有用字段级@JsonAdapter,也可以在这里全局注册适配器 // .add(BooleanToIntAdapter()) .build()
为什么之前的方案不生效?
- @Transient注解:这个注解会让Moshi完全忽略该字段,不管API是否返回,所以无法获取到存在时的字段值。
- 可空Int类型:Moshi没有内置的布尔值到Int?的转换器,当API返回布尔值时,会触发类型不匹配的错误。
测试场景覆盖
这个方案可以处理所有你的需求场景:
- API返回
"recommended": true→ 解析后recommended = 1 - API返回
"recommended": false→ 解析后recommended = 0 - API返回
"recommended": 3→ 解析后recommended = 3 - API不返回该字段 → 解析后使用默认值
recommended = 0
内容的提问来源于stack exchange,提问作者ant2009
相关产品推荐
相关产品推荐

