到目前为止,我一直在使用OkHttp来处理我的网络请求,但现在我想要使用Retrofit(v2)。 我与之通信的服务器要求AuthToken作为Url(GET请求)的一部分或Body(POST请求)的一部分。 我还需要将请求创建与执行分开,这是一个很好的改进功能,即我可以传递Call对象并稍后执行/排队。使用Retrofit/OkHttp修改POST请求正文
最难的部分是AuthToken在创建请求时可能不可用,我需要在它执行之前对其进行修改。到目前为止,我一直在创建时添加一个虚拟authToken,并在执行之前进行替换。 对于GET请求,这非常简单,因为我可以将Interceptor添加到OkHttpClient中来修改请求Url,但修改POST请求的正文是我努力的事情。
那么,在Retrofit/OkHttp中是否支持这个用例呢? java.lang.IllegalStateException:
一些没有工作的示例代码,几乎会做的伎俩(尝试添加的authToken总是可用的时候,用结束!无分块编码或已知的内容长度不能流的请求体
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?难道gzip压缩? –
不,这不是gzipped,我只是不知道如何实现contentLength()。如果我把:return body.contentLength();我ge t“java.net.ProtocolException:期望的0字节但收到111” – pmellaaho