Okhttp + 改造@Body请求 - 传输编码:已分块添加



我在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);
   }
});

我希望能够发送带有RequestBody但没有chunked标头的@POST...

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

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

但我想避免在发送之前解析所有对象以String

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

当 Retrofit 事先不知道请求正文的完整长度时,将使用Transfer-encoding: chunked。即。当 RequestBody.contentLength(( 返回 -1 时。您需要编写一些代码,将未知长度的请求正文转换为已知长度的请求正文。您可以像这样执行此操作:

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

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

最新更新