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

Moshi配合Retrofit序列化动态内部类如何避免转义和额外字段?

问题根因
  1. 之前的自定义适配器toJson方法返回String类型,Moshi会将该字符串作为JSON字符串值处理,自动添加外层引号、转义内部双引号,属于预期行为,不是bug。
  2. PolymorphicJsonAdapterFactory强制要求添加类型标识字段用于反序列化区分,无法满足无额外字段的纯序列化需求。
解决方案

直接改写自定义适配器,通过JsonWriter直接控制序列化输出,不需要返回字符串,Moshi不会额外包裹内容,也不会添加多余字段:

import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson

class AnimalAttributesAdapter {
    @ToJson
    fun toJson(writer: JsonWriter, value: AnimalAttributes?, moshi: Moshi) {
        // 空值处理
        if (value == null) {
            writer.nullValue()
            return
        }
        // 按实际类型获取对应子类的自动生成适配器
        val adapter = when (value) {
            is DogAttributes -> moshi.adapter(DogAttributes::class.java)
            is CatAttributes -> moshi.adapter(CatAttributes::class.java)
            else -> throw UnsupportedOperationException("不支持的属性类型: $value")
        }
        // 直接将子类序列化结果写入当前节点
        adapter.toJson(writer, value)
    }
}
配置方式

保持原有Moshi配置逻辑即可,无需其他改动:

val moshi = Moshi.Builder()
    .add(AnimalAttributesAdapter())
    // 其他适配器配置
    .build()
序列化效果

传入DogAttributes实例的最终请求体符合预期:

{"name":"my pet name","attributes":{"bark":true,"bite":false}}
注意事项

保留各子类的@JsonClass(generateAdapter = true)注解,Moshi会使用自动生成的高性能适配器完成子类序列化,无需手动处理字段映射。


内容的提问来源于stack exchange,提问作者mtrakal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:57:02