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

如何在转换为实体类前修改Retrofit JSON响应的根节点?

优化方案:单解析流程实现

完全可以通过一次解析完成需求,核心思路是直接使用Gson的JsonReader流式解析响应体,跳过无关字段,直接读取result并转换为T,同时捕获错误信息。这种方式避免了中间的字符串转换和二次解析,性能更优。

步骤1:替换GsonResponseBodyConverter为优化版本

internal class OptimizedGsonResponseBodyConverter<T>(
    private val gson: Gson,
    private val adapter: TypeAdapter<T>
) : Converter<ResponseBody, T> {

    @Throws(IOException::class)
    override fun convert(value: ResponseBody): T {
        value.use { responseBody ->
            val jsonReader = gson.newJsonReader(responseBody.charStream())
            jsonReader.beginObject()
            
            var isDone = false
            var result: T? = null
            var errorMsg: String? = null
            
            while (jsonReader.hasNext()) {
                when (jsonReader.nextName()) {
                    "done" -> isDone = jsonReader.nextBoolean()
                    "response" -> {
                        if (isDone) {
                            // 仅在成功时解析response中的result
                            jsonReader.beginObject()
                            while (jsonReader.hasNext()) {
                                if (jsonReader.nextName() == "result") {
                                    result = adapter.read(jsonReader)
                                } else {
                                    jsonReader.skipValue() // 跳过response中的其他字段
                                }
                            }
                            jsonReader.endObject()
                        } else {
                            jsonReader.skipValue() // 失败时跳过response字段
                        }
                    }
                    "error" -> {
                        if (!isDone) {
                            // 仅在失败时解析error中的message
                            jsonReader.beginObject()
                            while (jsonReader.hasNext()) {
                                if (jsonReader.nextName() == "message") {
                                    errorMsg = jsonReader.nextString()
                                } else {
                                    jsonReader.skipValue() // 跳过error中的其他字段
                                }
                            }
                            jsonReader.endObject()
                        } else {
                            jsonReader.skipValue() // 成功时跳过error字段
                        }
                    }
                    else -> jsonReader.skipValue() // 跳过其他未知字段
                }
            }
            
            jsonReader.endObject()
            
            return result ?: throw ProxyExecutionException(errorMsg ?: "响应解析失败:无有效结果或错误信息")
        }
    }
}

步骤2:更新ProxyGsonConverterFactory返回优化后的转换器

只需修改responseBodyConverter方法,返回OptimizedGsonResponseBodyConverter即可:

override fun responseBodyConverter(
    type: Type, annotations: Array<Annotation>, retrofit: Retrofit
): Converter<ResponseBody, *> {
    val adapter = gson.getAdapter(TypeToken.get(type))
    return OptimizedGsonResponseBodyConverter(gson, adapter)
}

方案优势

  • 单次解析:直接流式读取响应体,无需将整个JSON转为JSONObject或中间字符串,彻底消除二次解析的性能损耗。
  • 灵活兼容:无需修改Retrofit接口的返回类型,保持原有T类型的定义。
  • 错误处理:准确捕获错误场景中的message字段,抛出自定义异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:18:09