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

如何在OkHttp3 Interceptor中为请求体添加公共JSON字段?

在OkHttp3拦截器中统一添加通用JSON请求字段

要解决这个问题,核心思路是重新构建请求体——因为OkHttp的RequestBody是不可变的,我们需要读取原请求体的JSON内容,注入通用字段后生成新的请求体,再替换原请求继续执行。下面是具体实现步骤和代码:

实现步骤

  • 先判断原请求是否为JSON类型(避免处理表单、二进制等非JSON请求)
  • 读取原请求体的JSON内容,转换为可修改的JsonObject
  • 注入通用字段(比如traceId)
  • 将修改后的JSON转换为新的RequestBody
  • 构建新的请求,替换原请求后继续执行拦截链

完整代码实现

因为你的Retrofit已经使用了GsonConverterFactory,项目里应该已经引入了Gson依赖,直接修改MyInterceptor即可:

import com.google.gson.JsonObject
import com.google.gson.JsonParser
import okhttp3.*
import okio.Buffer
import java.nio.charset.Charset

class MyInterceptor : Interceptor {
    private val UTF8 = Charset.forName("UTF-8")
    private val fixedTraceId = "abc123" // 你的通用字段值,若需动态生成可调整逻辑

    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val originalBody = originalRequest.body()

        // 1. 无请求体或非JSON请求直接放行
        if (originalBody == null || !isJsonRequest(originalRequest)) {
            return chain.proceed(originalRequest)
        }

        // 2. 读取原请求体的JSON内容
        val buffer = Buffer()
        originalBody.writeTo(buffer)
        val originalJsonStr = buffer.readString(UTF8)
        val jsonObject = JsonParser.parseString(originalJsonStr).asJsonObject

        // 3. 注入通用字段
        jsonObject.addProperty("traceId", fixedTraceId)

        // 4. 生成新的请求体
        val newBody = RequestBody.create(
            originalBody.contentType(),
            jsonObject.toString()
        )

        // 5. 构建新请求并执行
        val newRequest = originalRequest.newBuilder()
            .method(originalRequest.method(), newBody)
            .build()

        return chain.proceed(newRequest)
    }

    // 判断请求是否为JSON类型
    private fun isJsonRequest(request: Request): Boolean {
        val contentType = request.body()?.contentType()
        return contentType != null && contentType.subtype.contains("json", ignoreCase = true)
    }
}

注意事项

  • 非JSON请求兼容:代码会自动跳过表单、二进制等非JSON请求,若需要处理这类请求,可以单独扩展逻辑。
  • 请求体重复读取问题:使用Buffer读取原请求体,不会影响后续请求执行,因为Buffer支持重复读取。
  • 动态字段支持:如果traceId需要每个请求生成不同的值(比如UUID),只需修改fixedTraceId的生成逻辑,注意保证线程安全即可。
  • Content-Length自动处理:OkHttp会自动计算新请求体的Content-Length,无需手动设置,除非你手动指定了原请求的该头字段,此时需要同步更新。

这样修改后,所有JSON类型的POST/PUT请求都会自动带上traceId字段啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:58:01