到目前为止,我一直在使用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();
}
};
}
});
答案 0 :(得分:0)
目前我不支持我要求的用例,所以我为Retrofit创建了一个新问题,请参阅Argument pre-processor, deserialized post-processor #816