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
相关产品推荐
相关产品推荐

