Retrofit是一个非常优秀的网络库,默认支持OkHttp,Retrofit与OkHttp共同出自于Square公司,Retrofit其实就是对OkHttp做了一层封装。把网络请求都交给给了OkHttp,我们只需要通过简单的配置就能使用Retrofit来进行网络请求了。
Retrofit现在最新版本是2.1,OkHttp最新版本是3.4.1,两者相比前一代版本都有较大的改动,由于本文重点是描述如何在网络请求中获取参数,如需了解更多请关注
Retrofit
及
OkHttp
官网。下文分别以Retrofit1.x+OKHttp2.x和Retrofit2.x+OKHttp3.x进行讲解。
1、Retrofit1.x+OKHttp2.x
点我达项目由于上线已经一年多,使用的版本比较低,Retrofit版本为1.9,OKHttp版本为2.5。如需获取请求参数,为了统一处理第一想法就是通过拦截器实现,Retrofit及OkHttp都支持拦截器,但是Retrofit拦截器却没有提供获取请求参数内容的方法。所以如果要在Retrofit层做处理,可以采取另外一方式。Retrofit支持自定义client,我们可以继承OkClient,获取到参数进行相关的处理。相关代码如下:
public class MyClient extends OkClient {
public MyClient(OkHttpClient client) {
super(client);
}
@Override
public Response execute(Request request) throws IOException {
//在这里获取到request后就可以做任何事情了
return super.execute(request);
}
}
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setClient(new MyClient(new OkHttpClient()));
RestAdapter adapter = builder.build();
那么在OkHttp层怎么做呢?使用拦截器,代码如下:
okHttpClient.networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException{
Request request = chain.request();
//在这里获取到request后就可以做任何事情了
return null;
}
});
2、Retrofit2.x+OKHttp3.x
如果在项目中希望使用响应式编程,那么Retrofit就需要更新至2.x版本,同时需要更新OkHttp至3.x版本。 Retrofit2.x有个比较大的变化点就是不再支持自定义网络client必须使用OKHttp3.x, 网络相关全部交给OKHttp,很多处理方式需要做出改动,比如只能使用OKHttp提供的拦截器。此时如需获取参数,只能在OKHttp上做文章,比如重写OKHttp或者使用拦截器。这里只介绍拦截器的方式,具体代码如下:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
Interceptor myInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//在这里获取到request后就可以做任何事情了
Response response = chain.proceed(request);
return response;
}
};
Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiService.HOST)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
通过以上方式获取参数之后,就可以对参数进行统一处理了,比如加密或者增加请求头等。 另外Retroift和OKHttp的request也不一样,get方式都一样,post请求的时候获取参数的区别比较大,这里分别给出两者post请求获取参数的相关代码。
OKHttp3.x获取post请求参数body的方式:
RequestBody requestBody= request.body();
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
Charset charset = Charset.forName("UTF-8");
MediaType contentType = requestBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
String paramsStr = buffer.readString(charset);
Retrofit1.x获取post请求参数body的方式:
String bodyParams = "";
TypedOutput body = request.getBody();
if (body != null) {
try {
if (!(body instanceof TypedByteArray)) {
String bodyMime = body.mimeType();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
body.writeTo(baos);
body = new TypedByteArray(bodyMime, baos.toByteArray());
}
bodyParams = new String(((TypedByteArray) body).getBytes(),MimeUtil.parseCharset(body.mimeType()));
} catch (Exception e) {
e.printStackTrace();
}
}
对参数进行处理之后需要构建新的request,OKHttp3.x构建新的request:
Request.Builder requestBuilder = request.newBuilder();
if(request.body() instanceof FormBody){
FormBody.Builder newFormBody = new FormBody.Builder();
FormBody oldFormBody = (FormBody) request.body();
for(int i = 0;i<oldFormBody.size();i++){
newFormBody.addEncoded(oldFormBody.encodedName(i),oldFormBody.encodedValue(i));
}
newFormBody.add("sign","******");
requestBuilder.method(request.method(), newFormBody.build());
}
Request newRequest = requestBuilder.build();
Retrofit1.x构建新的Request:
TypedOutput body = new TypedByteArray(requestType, params.getBytes());
Request newRequest = new Request(request.getMethod(), url,request.getHeaders(), body);
好了,Android网络请求使用Retrofit+OkHttp,获取参数以及对参数修改之后重新构建request的方法和关键代码就介绍到这里。