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

从Gson迁移到Moshi时序列化List<ImageDTO>遇转义问题求助

解决Moshi序列化List时内部双引号转义问题

问题根源

你的自定义ImageDTO适配器如果是直接返回字符串类型的JSON内容(比如手动拼接的JSON字符串),Moshi会将其视为普通字符串处理,序列化列表时自动转义字符串内部的双引号。而Gson会自动识别这类字符串为JSON结构,不会额外转义。

解决方案:调整自定义适配器,直接使用JsonWriter写入JSON结构

不要让适配器返回字符串,而是通过JsonWriter直接写入JSON对象的字段,这样Moshi在序列化列表时会将每个元素识别为JSON对象,而非字符串,避免转义。

修正后的ImageDTO适配器

class ImageDtoAdapter {
    @ToJson
    fun toJson(writer: JsonWriter, image: ImageDTO) {
        writer.beginObject()
        // 逐个写入字段,示例以url字段为例
        writer.name("url").value(image.url)
        // 其他字段按同样方式写入,比如width、height等
        // writer.name("width").value(image.width)
        writer.endObject()
    }

    @FromJson
    fun fromJson(reader: JsonReader): ImageDTO {
        var url = ""
        // 可根据需要添加其他字段的默认值
        // var width = 0
        reader.beginObject()
        while (reader.hasNext()) {
            when (val fieldName = reader.nextName()) {
                "url" -> url = reader.nextString()
                // "width" -> width = reader.nextInt()
                else -> reader.skipValue() // 跳过未知字段
            }
        }
        reader.endObject()
        return ImageDTO(url) // 对应构造函数传入字段
    }
}

注册适配器到Moshi

val moshi = Moshi.Builder()
    .add(ImageDtoAdapter())
    .build()

备选方案:自定义List适配器(复用原有字符串逻辑时)

如果必须保留基于字符串的序列化逻辑(比如复用原Gson的代码),可以单独为List<ImageDTO>编写适配器,手动处理每个元素的序列化,避免转义:

class ImageListAdapter(private val imageAdapter: ImageDtoAdapter) {
    @ToJson
    fun toJson(writer: JsonWriter, images: List<ImageDTO>) {
        writer.beginArray()
        images.forEach { image ->
            // 直接调用ImageDTO的写入逻辑,绕过字符串转义
            imageAdapter.toJson(writer, image)
        }
        writer.endArray()
    }

    @FromJson
    fun fromJson(reader: JsonReader): List<ImageDTO> {
        val imageList = mutableListOf<ImageDTO>()
        reader.beginArray()
        while (reader.hasNext()) {
            imageList.add(imageAdapter.fromJson(reader))
        }
        reader.endArray()
        return imageList
    }
}

注册时注意顺序:

val moshi = Moshi.Builder()
    .add(ImageDtoAdapter())
    .add(ImageListAdapter(ImageDtoAdapter()))
    .build()

验证效果

序列化列表时,Moshi会生成正确的JSON数组,内部字段的双引号不会被转义:

[{"url":"https://example.com/image.jpg"},{"url":"https://example.com/image2.jpg"}]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:07:01