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

为何支持请求体的OkHttp POST请求缺失Content-Type请求头?

解决全局统一处理Content-Type请求头的问题

看起来你在Retrofit项目中遇到了Content-Type头自动处理不符合预期的情况,同时希望用全局拦截器替代逐个接口加注解的方案,我来给你梳理下可行的解决方案:

核心问题分析

你提到“不支持请求体的请求方法会被移除Content-Type头,但实际情况并非如此”,这大概率是因为Retrofit的默认逻辑被自定义拦截器、转换器或者特殊请求配置(比如GET方法带@Body注解)干扰了。既然你已经确认User-Agent头设置正常,说明全局拦截器的配置路径是通的,我们可以通过自定义Interceptor来完全掌控Content-Type的处理逻辑。

全局Interceptor实现方案

下面是一步到位的代码实现,能帮你统一处理所有请求的Content-Type头:

1. 编写自定义Content-Type拦截器

class ContentTypeInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        var modifiedRequest = originalRequest

        // 根据HTTP方法类型,精准控制Content-Type头
        when (originalRequest.method.uppercase()) {
            // 对不支持请求体的HTTP方法,强制移除Content-Type
            "GET", "HEAD", "DELETE", "OPTIONS", "TRACE", "CONNECT" -> {
                modifiedRequest = originalRequest.newBuilder()
                    .removeHeader("Content-Type")
                    .build()
            }
            // 对支持请求体的方法,自动补充默认Content-Type(如果未设置)
            "POST", "PUT", "PATCH" -> {
                if (originalRequest.headers("Content-Type").isEmpty()) {
                    modifiedRequest = originalRequest.newBuilder()
                        .addHeader("Content-Type", "application/json; charset=utf-8")
                        .build()
                }
            }
        }

        return chain.proceed(modifiedRequest)
    }
}

2. 将拦截器绑定到OkHttpClient

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(ContentTypeInterceptor())
    // 这里可以添加其他拦截器(比如日志、认证)或配置超时参数
    .build()

3. 把配置好的OkHttpClient传给Retrofit

val retrofit = Retrofit.Builder()
    .baseUrl("你的API基础地址")
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build()

val api = retrofit.create(Api::class.java)

额外说明

  • 优先级处理:如果某个特殊接口需要自定义Content-Type,直接在接口方法上添加@Headers("Content-Type: multipart/form-data")即可——Retrofit会优先使用方法级别的注解配置,不会被全局拦截器覆盖。
  • 异常场景排查:如果之前的自动移除逻辑失效,可能是你项目中的GsonConverter或者其他拦截器提前给请求加上了Content-Type头,导致Retrofit的默认清理逻辑没触发,用这个自定义拦截器可以强制覆盖处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:49:29