使用Retrofit / OkHttp时修改POST请求Body

时间:2015-10-07 09:17:34

标签: retrofit interceptor okhttp

到目前为止,我一直在使用OkHttp进行网络请求,但现在我想使用Retrofit(v2)。 我正在与之通信的服务器要求AuthToken作为Url(GET请求)或Body(POST请求)的一部分。 我还需要将请求创建与执行分开,这是一个非常好的Retrofit功能,即我可以传递Call对象并稍后执行/入队。

困难的部分是创建请求时AuthToken可能不可用,我需要在执行之前对其进行修改。到目前为止,我一直在创建时添加一个伪authToken,并在执行之前替换。 这对于GET请求来说非常简单,因为我可以将Interceptor添加到OkHttpClient来修改请求Url,但修改POST请求的主体是我正在努力的事情。

那么,在Retrofit / OkHttp中是否支持这个用例?

一些不能正常工作的示例代码(尝试在可用时始终添加authToken,最终得到:java.lang.IllegalStateException:无法在没有分块编码或已知内容长度的情况下流式传输请求主体!

client.networkInterceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            if (request.body() == null) {
                return chain.proceed(request);
            }

            Request authorizedRequest = request.newBuilder()
                    .method(request.method(), replaceDummyAuth(request.body()))
                    .build();
            return chain.proceed(authorizedRequest);
        }

        private RequestBody replaceDummyAuth(final RequestBody body) {
            return new RequestBody() {
                @Override
                public MediaType contentType() {
                    return body.contentType();
                }

                @Override
                public long contentLength() throws IOException {
                    return -1;
                }

                @Override
                public void writeTo(BufferedSink sink) throws IOException {
                    ParametersMap map = new ParametersMap();

                    BufferedSink authSink = Okio.buffer(sink);
                    body.writeTo(authSink);

                    String authToken = SessionManager.getAuthToken();
                    if(StringUtils.hasText(authToken)) {
                        map.put("authToken", authToken);
                        String paramString = map.getParameterString();
                        authSink.write(paramString.getBytes("UTF-8"));
                    }
                    authSink.close();
                }
            };
        }
    });

1 个答案:

答案 0 :(得分:0)

目前我不支持我要求的用例,所以我为Retrofit创建了一个新问题,请参阅Argument pre-processor, deserialized post-processor #816