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

Retrofit2与Gson:跳过无用根JSON节点反序列化数据

跳过无用根JSON节点直接解析内容的方案

当然可以!调用第三方API遇到这种外层冗余的JSON节点太常见了,咱们有好几种靠谱的方法能跳过那个多余的Response类,直接把内部字段解析到你想要的MyResponseClass里。

方法一:直接让JsonToKotlinClass生成目标类

最直接的方式就是修改插件的生成规则,让它自动扁平化根节点:

  • 打开Android Studio的设置(File > Settings > Plugins > JsonToKotlinClass > Settings)
  • 找到**「Root Element Handling」相关选项,选择「Flatten Root Element」**(不同版本插件的选项名称可能略有差异)
  • 把你的原始JSON响应粘贴进去,插件就会自动提取response节点下的字段,直接生成:
    data class MyResponseClass(
        val status: Status,
        val configuration: Configuration
    )
    
    同时也会生成Status和Configuration这两个内部数据类,完美跳过中间的Response类。

方法二:解析时手动跳过冗余节点(适合已生成类的场景)

如果已经用插件生成了原来的四个类,或者不想修改插件设置,可以在解析阶段手动定位到response节点再解析:

Gson示例

val gson = Gson()
// 先把原始JSON解析成JsonObject
val rawJsonObject = gson.fromJson(apiResponseString, JsonObject::class.java)
// 取出response节点的JSON字符串
val targetJson = rawJsonObject.getAsJsonObject("response").toString()
// 直接解析成目标MyResponseClass(注意这个类要包含status和configuration字段)
val myResponse = gson.fromJson(targetJson, MyResponseClass::class.java)

Moshi示例

val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter(JsonObject::class.java)
val rawJsonObject = jsonAdapter.fromJson(apiResponseString)
// 取出response节点
val targetJsonObject = rawJsonObject?.getAsJsonObject("response")
// 解析成目标类
val targetAdapter = moshi.adapter(MyResponseClass::class.java)
val myResponse = targetAdapter.fromJson(targetJsonObject.toString())

方法三:自定义解析适配器(优雅的长期方案)

如果这个API的所有响应都带有这个外层response节点,写一个自定义适配器可以统一处理,避免重复代码:

以Gson为例,实现一个TypeAdapterFactory:

class SkipRootResponseFactory : TypeAdapterFactory {
    override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
        val delegateAdapter = gson.getDelegateAdapter(this, type)
        return object : TypeAdapter<T>() {
            override fun write(out: JsonWriter, value: T?) {
                delegateAdapter.write(out, value)
            }

            override fun read(`in`: JsonReader): T {
                // 跳过外层的response节点
                `in`.beginObject()
                while (`in`.nextName() != "response") {
                    `in`.skipValue()
                }
                val result = delegateAdapter.read(`in`)
                `in`.endObject()
                return result
            }
        }
    }
}

初始化Gson时注册这个工厂:

val gson = GsonBuilder()
    .registerTypeAdapterFactory(SkipRootResponseFactory())
    .create()
// 现在可以直接把原始JSON解析到目标类
val myResponse = gson.fromJson(apiResponseString, MyResponseClass::class.java)

这样以后所有带外层response节点的响应都能自动跳过冗余节点,直接解析到你想要的类结构里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:55:35