Okhttp + Retrofit @Body请求 - Transfer-Encoding:chunked added

时间:2018-01-17 09:57:18

标签: java android retrofit okhttp

我在Android中使用Retrofit和Okhttp时遇到问题。问题是当我使用带有身体负载的请求时会自动添加标头Transfer-Encoding: chunked,如下所示:

@POST("members")
Observable<Response<Void>> createMember(@Header(X_CLIENT_AUTHORIZATION) 
String clientAuthorization, @Body RequestBody payload);

然后,自动添加标题Transfer-Encoding: chunked,由于某种原因,服务器无法处理。我希望身体是纯文本的json。服务器认为它是一个文件。

最糟糕的是,如果我尝试添加拦截器并使用removeHeader,甚至无法工作。

httpClient.addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
       Request original = chain.request();
       Request.Builder requestBuilder = original.newBuilder()
               .removeHeader("Transfer-Encoding");

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

我希望能够使用@POST发送RequestBody但不使用chunked标题...

如果我这样使用它,它就不会添加标题:

@POST("members")
Observable<Response<Void>> createMember(@Header(X_CLIENT_AUTHORIZATION) String clientAuthorization, @Body **String** payload);

但我希望在发送之前避免将所有对象解析为String

有没有人知道如何删除此类请求并将对象作为纯文本json发送?

1 个答案:

答案 0 :(得分:2)

当Retrofit事先不知道您的请求正文的全长时,会使用

Transfer-encoding: chunked。 IE浏览器。当RequestBody.contentLength()返回-1时。您需要编写一些代码,将未知长度的RequestBody转换为已知长度的RequestBody。您可能会这样做:

RequestBody original = ...
Buffer buffer = new Buffer();
original.writeTo(buffer);
ByteString bytes = buffer.snapshot();
RequestBody fixedLength = RequestBody.create(bytes, original.contentType());

如果你在拦截器中执行此操作,则甚至不需要更改调用代码。