版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yrmao9893/article/details/70436940
转载请说明出处:
前言:我相信现在很多人都在用OKhttp作为网络请求库,为什么OKhttp会受到这么多人的青睐呢,谷歌也不例外(据我了解到它是唯一一个被谷歌认可的第三方网络请求库),
原因有很多,对于我来说,OKhttp对我最受用的是它的拦截器机制
拦截器的分类:
1.网络拦截器
2.应用拦截器
借鉴文章: http://www.jianshu.com/p/2710ed1e6b48,对两种拦截器的详细介绍
终于开始文章的主题了:
原理:利用应用拦截器对请求进行拦截,重定向
步骤:1.发起一个网络请求,拦截到响应结果
2.判断响应结果是否为token失效
3.如果token失效,获取新的token
4.携带新的token,重新请求
好了大概步骤已经梳理好了,判断token失效的方法是什么呢?
大概有两种:
1.http code 标记一个不为200的code(与服务器商定好的:比如当返回的code值为201则表示token失效)
2.在响应数据的data里面例如:{"requestStatus":{"code":42441,"msg":"token失效请重新登录","timestamp":1492847318460},"data":""}
到了这里那我们开始吧:
第一种的验证方法:
public static void tokenInterceptor1(){
new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//拿到请求体,并添加header携带上token
Request mRequest = chain.request().newBuilder()
.addHeader("Token", Token)
.build();
//拿到响应体
Response mResponse = chain.proceed(mRequest);
//假设返回的code为201时表示token失效
if (mResponse.code()==201){
//重新获取新token
//这用了一个特殊接口来获取新的Token
Call<String> call = RetrofitFactory.getInstence().API().loginByToken("123456", Token);
//拿到请求体
Request tokenRequest = call.request();
//获取响应体
Response tokenResponse = chain.proceed(tokenRequest);
//我这假设新的token是在header里返回的
//我们拿到新的token头
List<String> listHeader = tokenResponse.headers().values("Token");
if (listHeader != null) {
//重新赋值到新的token
Token = listHeader.get(0);
}
//这是只需要替换掉之前的token重新请求接口就行了
Request newRequest = mRequest.newBuilder()
.header("Token", Token)
.build();
return chain.proceed(newRequest);
}
return mResponse;
}
};
}
第二种的方法
public static Interceptor tokeInterceptor2() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
/**
* 1.拦截到返回的数据
* 2.判断token是否失效
* 3.失效获取新的token
* 4.重新请求接口
*/
//拿到请求体,并添加header携带上token
Request mRequest = chain.request().newBuilder()
.addHeader("Token", Token)
.build();
//拿到响应体
Response mResponse = chain.proceed(mRequest);
ResponseBody responseBody = mResponse.body();
//得到缓冲源
BufferedSource source = responseBody.source();
//请求全部
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
//读取返回数据
String bodyString = buffer.clone().readString(charset);
if (bodyString != null) {
//处理返回的数据我这创建了一个BaseEntity来将数据转化为对象
BaseEntity bean = JSON.parseObject(bodyString, BaseEntity.class);
//假设当返回的code为42444时token失效
if (bean.getCode() == 42444) {
//重新获取新token
//这用了一个特殊接口来获取新的Token
Call<String> call = RetrofitFactory.getInstence().API().loginByToken("123456", Token);
//拿到请求体
Request tokenRequest = call.request();
//获取响应体
Response tokenResponse = chain.proceed(tokenRequest);
//我这假设新的token是在header里返回的
//我们拿到新的token头
List<String> listHeader = tokenResponse.headers().values("Token");
if (listHeader != null) {
//重新赋值到新的token
Token = listHeader.get(0);
}
//这是只需要替换掉之前的token重新请求接口就行了
Request newRequest = mRequest.newBuilder()
.header("Token", Token)
.build();
return chain.proceed(newRequest);
}
}
return chain.proceed(mRequest);
}
};
}
最后贴一个实体类BaseEntity
public class BaseEntity<T> {
private static int SUCCESS_CODE=42440;//成功的code
private int code;
private String msg;
private T data;
public boolean isSuccess(){
return getCode()==SUCCESS_CODE;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}