You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:52:35