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

OkHttpClient自动添加Charset=Utf-8致Azure OpenAI API请求报错

解决OkHttpClient自动添加charset=utf-8到Content-Type的问题

问题原因

OkHttpClient或配套的Converter(如GsonConverterFactory)处理JSON请求体时,会自动为Content-Type头追加; charset=utf-8,导致Azure OpenAI接口因不接受该格式头而报错。

解决方案

方案1:自定义RequestBody,手动指定无charset的MediaType

构建请求体时,直接使用不含charset的application/json MediaType,避免自动追加:

import okhttp3.MediaType
import okhttp3.RequestBody

// 定义不含charset的MediaType
val JSON_MEDIA_TYPE = MediaType.get("application/json")

// 构建请求体
val jsonPayload = "{\"messages\": [...]}".trimIndent()
val requestBody = RequestBody.create(JSON_MEDIA_TYPE, jsonPayload)

// 构建请求
val request = Request.Builder()
    .url("YOUR_AZURE_OPENAI_ENDPOINT")
    .post(requestBody)
    .build()

方案2:添加OkHttp拦截器,强制覆盖Content-Type头

通过拦截器统一修改所有请求的Content-Type,确保始终为application/json:

import okhttp3.OkHttpClient
import okhttp3.Request

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor { chain ->
        val originalRequest = chain.request()
        // 覆盖Content-Type头,移除charset信息
        val modifiedRequest = originalRequest.newBuilder()
            .header("Content-Type", "application/json")
            .build()
        chain.proceed(modifiedRequest)
    }
    .build()

方案3:自定义Retrofit Converter(若使用Retrofit)

如果项目使用Retrofit,默认的GsonConverterFactory会自动添加charset,可自定义Converter避免该行为:

import com.google.gson.Gson
import okhttp3.MediaType
import okhttp3.RequestBody
import retrofit2.Converter
import retrofit2.Retrofit
import java.lang.reflect.Type

class CustomGsonRequestBodyConverter<T>(private val gson: Gson, private val type: Type) : Converter<T, RequestBody> {
    private val JSON_MEDIA_TYPE = MediaType.get("application/json")

    override fun convert(value: T): RequestBody {
        val jsonString = gson.toJson(value, type)
        return RequestBody.create(JSON_MEDIA_TYPE, jsonString)
    }
}

// 构建Retrofit时使用自定义Converter
val retrofit = Retrofit.Builder()
    .baseUrl("YOUR_AZURE_OPENAI_BASE_URL")
    .client(okHttpClient)
    .addConverterFactory(object : Converter.Factory() {
        override fun requestBodyConverter(
            type: Type,
            parameterAnnotations: Array<Annotation>,
            methodAnnotations: Array<Annotation>,
            retrofit: Retrofit
        ): Converter<*, RequestBody>? {
            return CustomGsonRequestBodyConverter(Gson(), type)
        }
    })
    .build()

验证方法

发送请求前,可通过拦截器打印请求头,确认Content-Type是否为纯application/json:

.addInterceptor { chain ->
    val request = chain.request()
    println("Content-Type: ${request.header("Content-Type")}")
    chain.proceed(request)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:52:24