Retrofit、OKHttp访问接口时添加公共参数

使用场景

在实际的开发中,有时候后台需要在每个接口中带有一些公共的参数,比如当前APP的版本、访问时间、或者一些约定的秘钥等等,当然我们可以在每个接口中都添加这样的参数就可以了,但是那样做对一个程序员来说肯定不够优雅,所以就想怎么在接口请求的时候统一的对所有的接口加上这些参数。

解决办法

经过查阅资料发现可以使用OKHttp的拦截器(Interceptor)实现。

使用方法

  • 新建一个MyInterceptor实现Interceptor接口;

  • 重写intercept方法。

具体代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RequestBody requestBody = request.body();
if (request.method().equals("GET")) {
HttpUrl url = request.url();
Set<String> parameterNames = url.queryParameterNames(); //
for (String key : parameterNames) { //循环参数列表
if (BuildConfig.DEBUG) Log.e("MyInterceptor", key); // 如果要对已有的参数做进一步处理可以这样拿到参数
} //只添加的话 倒是没有必要
String sUrl = url.toString();
int index = sUrl.indexOf("?");
if (index > 0) {
sUrl = sUrl + "所需参数拼接"; //所需参数拼接 ==>就是类似于 name=123&version=12&....这些
} else {
sUrl = sUrl + "?" + "所需参数拼接";
}
request = request.newBuilder().url(sUrl).build(); //重新构建
} else if (request.method().equals("POST")) {
if (requestBody instanceof FormBody) {
FormBody.Builder builder = new FormBody.Builder();
FormBody formBody = (FormBody) requestBody;
for (int i = 0; i < formBody.size(); i++) { // 如果要对已有的参数做进一步处理可以这样拿到参数
Log.e("MyInterceptor", "encodedNames:" + formBody.encodedName(i) + " encodedValues:" + formBody.encodedValue(i));
builder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
}
builder.addEncoded("参数1", "值1"); //添加公共参数
builder.addEncoded("参数2", "值2");
builder.addEncoded("参数3", "值3");
request = request.newBuilder().post(builder.build()).build(); //重新构建
}
}
return chain.proceed(request);
}
  • 在OKHttp或Retrofit中使用

两者是一样的都是通过OKHttp来添加,如下:

1
2
3
4
5
6
7
8
9
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new MyInterceptor()) //使用拦截器
.connectTimeout(15, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://192.168.1.59:8080/")
.addConverterFactory(GsonConverterFactory.create())
.build();
networkService = retrofit.create(NetworkService.class);

如上所示,就完成了普通的GET和POST方式使用时对所有的接口统一添加公共接口。

结语

本人最初是为了在访问后台接口的时候对所有的参数进行统一的加密,前后端使用同样的加密算法以及秘钥,但是在具体使用过程中如何传送秘钥,以及如何保证秘钥的传递安全以及加密算法的安全是需要重点考量的。
通过拦截器可以做很多事情,例如缓存等。

参考文章:

http://www.jianshu.com/p/2710ed1e6b48