Retrofit/OkHttp 移除 Transfer-Encoding header
Retrofit/OkHttp removes Transfer-Encoding header
我需要我的请求包含 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");
无效。
为什么改造会无缘无故地删除这个 header?
header 存在于拦截器中,顺便说一句。
Call
object 的 originalRequest
字段也包含 header,但 Response
object 的 rawResponse.request
没有,即使所有其他 header 都很好。
Retrofit 提供了两个选项来定义 HTTP 请求 header 字段:静态和动态。
通过这种方式你传递的是静态请求header,如果你使用日志拦截器
,你也可以在日志中看到这个header
@Headers({"Transfer-Encoding: chunked", "Content-Type: application/foo"})
@POST("/api/upload")
Call<UploadResponse> uploadFoo(@Body RequestBody body)
而第二种方式是动态传递header,你也可以在log
中看到这个header
@POST("/api/upload")
Call<UploadResponse> uploadFoo(@Body RequestBody body, @Header("Transfer-Encoding") String te)
最后但同样重要的是,如果你需要 header 字段在几乎每个请求中包含它的值,你可以使用拦截器来添加这条信息,比如
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)
那么这将覆盖 headers,即使已经有一个现有的 header 具有相同的密钥标识符。您可以使用 .addHeader(key, val)
使用相同的密钥添加多个请求 header
根据文档,执行此操作的正常方法是在 @Body 之前使用 @Chunked 注释。
Call<UploadResponse> uploadFoo(@Chunked @Body RequestBody body)
您可以选择使用 Service 方法强制发送分块内容:
Service.sendChunked(@Chunked @Body Repo repo);
中定义
不可能,OkHttp内部决定的,取决于RequestBody的类型
我需要我的请求包含 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");
无效。
为什么改造会无缘无故地删除这个 header?
header 存在于拦截器中,顺便说一句。
Call
object 的 originalRequest
字段也包含 header,但 Response
object 的 rawResponse.request
没有,即使所有其他 header 都很好。
Retrofit 提供了两个选项来定义 HTTP 请求 header 字段:静态和动态。
通过这种方式你传递的是静态请求header,如果你使用日志拦截器
,你也可以在日志中看到这个header@Headers({"Transfer-Encoding: chunked", "Content-Type: application/foo"})
@POST("/api/upload")
Call<UploadResponse> uploadFoo(@Body RequestBody body)
而第二种方式是动态传递header,你也可以在log
中看到这个header@POST("/api/upload")
Call<UploadResponse> uploadFoo(@Body RequestBody body, @Header("Transfer-Encoding") String te)
最后但同样重要的是,如果你需要 header 字段在几乎每个请求中包含它的值,你可以使用拦截器来添加这条信息,比如
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)
那么这将覆盖 headers,即使已经有一个现有的 header 具有相同的密钥标识符。您可以使用 .addHeader(key, val)
根据文档,执行此操作的正常方法是在 @Body 之前使用 @Chunked 注释。
Call<UploadResponse> uploadFoo(@Chunked @Body RequestBody body)
您可以选择使用 Service 方法强制发送分块内容:
Service.sendChunked(@Chunked @Body Repo repo);
中定义
不可能,OkHttp内部决定的,取决于RequestBody的类型