您的位置:

提示IOException("PROTOCOL_ERROR response malformed: mixed case name: ${name.utf8()}")的解决方案

  发布时间:2025-01-18 18:06:19
该内容介绍了OkHttp出现异常的原因和解决方案,提供了构建符合HTTP/2标准请求的示例代码。同时给出了一个避免大小写混合header字段名导致异常的示例。

问题原因

OkHttp出现该异常的原因是HTTP/2协议要求header field names必须是小写,然而在收到包含大写字符的header field name时,OkHttp会认为这是一个不符合规范的响应,进而抛出该异常。

解决方案

问题的根本原因在于在HTTP/2标准中,header的name必须是小写,而当以大小写混合形式出现时会导致这个异常。解决这个问题的方法是在构建请求时确保header的name都是小写形式,确保符合HTTP/2标准。以下是一个示例代码,展示了如何正确构建一个使用小写header name的OkHttp请求:


OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://www.example.com")
  .header("content-type", "application/json")
  .header("user-agent", "OkHttp")
  .get()
  .build();

try {
  Response response = client.newCall(request).execute();
  // 处理响应
} catch (IOException e) {
  e.printStackTrace();
}

具体例子

当出现IOException("PROTOCOL_ERROR response malformed: mixed case name: ${name.utf8()}")错误时,这通常是由于服务器返回的响应中包含了大小写混合的header字段名导致的。要正确使用OkHttp并避免这个问题,需要确保在构建请求时不会出现大小写混合的header字段名。可以通过自定义Interceptor来规范化header字段名的大小写。 下面是一个示例代码,展示了如何正确使用OkHttp并避免该问题:


import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class OkHttpExample {

    public void makeRequest() {
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new HeaderInterceptor())
                .build();

        Request request = new Request.Builder()
                .url("https://api.example.com/data")
                .get()
                .build();

        try {
            Response response = client.newCall(request).execute();
            // Process the response as needed
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class HeaderInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();

            // Create a new request builder with normalized header names
            Request.Builder requestBuilder = originalRequest.newBuilder();
            for (String headerName : originalRequest.headers().names()) {
                requestBuilder.removeHeader(headerName);
                requestBuilder.addHeader(headerName.toLowerCase(), originalRequest.header(headerName));
            }

            Request newRequest = requestBuilder.build();
            return chain.proceed(newRequest);
        }
    }
}

在这个示例中,通过自定义Interceptor,在发送请求前规范化header字段名的大小写,从而避免出现PROTOCOL_ERROR response malformed错误。