首页 > 解决方案 > Retrofit/OkHttp 移除 Transfer-Encoding 标头

问题描述

我需要我的请求来包含 header Transfer-Encoding: chunked。但是无论我@Headers是在方法中添加注解还是添加@Header注解和参数,它都会从最终请求中消失。

@POST("/api/upload").                   // this header is added correctly
@Headers({"Transfer-Encoding: chunked", "Content-Type: application/foo"})
Call<UploadResponse> uploadFoo(@Body RequestBody body)

或者

@POST("/api/upload").
@Headers("Content-Type: application/foo")
Call<UploadResponse> uploadFoo(@Body RequestBody body, @Header("Transfer-Encoding") te)

并称它为

uploadFoo(body, "chunked");

不起作用。

为什么改造会无缘无故删除此标头?

顺便说一句,标头存在于拦截器中。

Call对象的字段也originalRequest包含标题,但Response对象rawResponse.request不包含,即使所有其他标题都很好。

标签: javahttpretrofitretrofit2okhttp

解决方案


Retrofit 提供了两个选项来定义 HTTP 请求头字段:静态和动态。

通过这种方式,您正在传递静态请求标头,如果您使用日志拦截器,您也可以在日志中看到此标头

@Headers({"Transfer-Encoding: chunked", "Content-Type: application/foo"})
@POST("/api/upload")                  
Call<UploadResponse> uploadFoo(@Body RequestBody body)

第二种方法是传递动态标头,您也可以在日志中看到此标头

@POST("/api/upload")
Call<UploadResponse> uploadFoo(@Body RequestBody body, @Header("Transfer-Encoding") String te)

最后但并非最不重要的一点是,如果您需要在几乎每个请求中包含其值的标头字段,您可以使用拦截器添加这条信息,例如

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();  
httpClient.addInterceptor(new Interceptor() {  
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request original = chain.request();

        // Request customization: add request headers
        Request.Builder requestBuilder = original.newBuilder()
                .header("Transfer-Encoding", "chunked"); // <-- this is the important line

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

OkHttpClient client = httpClient.build(); 

现在棘手的部分在这里,如果在您的拦截器中使用它.header(key, val),那么即使已经存在具有相同密钥标识符的标头,这也会覆盖标头。您可以使用相同的键添加多个请求标头.addHeader(key, val)


推荐阅读