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

Android Moshi自定义布尔适配器失效求助:JSON布尔值格式兼容异常

问题解答

核心原因

你遇到的问题是Moshi适配器的优先级与注册方式不匹配:

  • 虽然你在Moshi全局Builder里注册了BooleanAdapter,但同时又在字段上添加了@JsonAdapter(BooleanAdapter::class)注解
  • 当使用@JsonClass(generateAdapter = true)时,字段上的@JsonAdapter要求传入的是适配器工厂(Factory),而非直接传入适配器类。直接传适配器类会导致Moshi无法正确创建适配器实例,最终还是使用默认的布尔类型适配器,自然无法解析字符串形式的"true"。

解决方案(两种可选)

方案一:移除字段上的@JsonAdapter注解,仅保留全局注册

既然已经在Moshi全局Builder中注册了BooleanAdapter,它会自动作用于所有Boolean类型的字段,不需要再在每个字段上重复添加注解。

修改后的数据类:

@JsonClass(generateAdapter = true)
data class ItemResponse(
    @Json(name = "mSet") val IsSet: Boolean,
    @Json(name = "name") val name: String,
    @Json(name = "isPrimary") val isPrimary: Boolean
)

方案二:给BooleanAdapter添加Factory,并修改字段注解

如果你需要仅在特定字段上使用该适配器(而非全局),需要给适配器添加对应的Factory实现:

  1. 修改BooleanAdapter,添加内部Factory类:
class BooleanAdapter : JsonAdapter<Boolean>() {
    @FromJson
    override fun fromJson(reader: JsonReader): Boolean {
        return when (reader.peek()) {
            JsonReader.Token.BOOLEAN -> reader.nextBoolean()
            JsonReader.Token.STRING -> {
                when (val value = reader.nextString()) {
                    "true", "True", "TRUE", "1" -> true
                    "false", "False", "FALSE", "0" -> false
                    else -> throw JsonDataException("Invalid boolean value: $value")
                }
            }
            JsonReader.Token.NUMBER -> {
                when (val value = reader.nextInt()) {
                    0 -> false
                    1 -> true
                    else -> throw JsonDataException("Invalid boolean value: $value")
                }
            }
            else -> throw JsonDataException("Expected boolean or string or int value but was ${reader.peek()}")
        }
    }

    @ToJson
    override fun toJson(writer: JsonWriter, value: Boolean?) {
        writer.value(value)
    }

    companion object Factory : JsonAdapter.Factory {
        override fun create(type: Type, annotations: Set<Annotation>, moshi: Moshi): JsonAdapter<*>? {
            return if (type === Boolean::class.javaObjectType || type === Boolean::class.java) {
                BooleanAdapter()
            } else {
                null
            }
        }
    }
}
  1. 修改数据类的字段注解,指向Factory类:
@JsonClass(generateAdapter = true)
data class ItemResponse(
    @field:JsonAdapter(BooleanAdapter.Factory::class)
    @Json(name = "mSet") val IsSet: Boolean,

    @Json(name = "name") val name: String,

    @field:JsonAdapter(BooleanAdapter.Factory::class)
    @Json(name = "isPrimary") val isPrimary: Boolean
)

验证测试

使用上述任一方案后,Moshi就能正确解析JSON中字符串形式的"true"/"false"、数字0/1以及原生布尔值true/false了。


内容的提问来源于stack exchange,提问作者Ujjwal Kumar Maharana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:42:38