项目需求
当请求某个接口的时候,我们会在请求的header中携带token消息,但是发现token失效,接口请求报错,怎么马上刷新token,然后重复请求方才那个接口呢?这个过程应该说对用户来说是无感的。
解决方案
- 通过拦截器,获取返回的数据
- 判断token是否过期
- 如果token过期则刷新token
- 使用最新的token,重新请求网络数据
实现拦截器
public class TokenInterceptor implements Interceptor {
private static final String TAG = "TokenInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
Log.d(TAG, "response.code=" + response.code());
//判断token过期
if (isTokenExpired(response)) {
//同步请求方获取最新的Token
String newToken = getNewToken();
//使用新的Token,创建新的请求
Request newRequest = chain.request()
.newBuilder()
.header("Authorization", Url.BEARER +" " + newToken)
.build();
//重新请求
return chain.proceed(newRequest);
}
return response;
}
/**
* 根据Response,判断Token是否失效
*/
private boolean isTokenExpired(Response response) {
if (response.code() == 401) {
return true;
}
return false;
}
/**
* 同步请求方式,获取最新的Token
* 此处需考虑并发问题,多请求时可能同时去刷新token导致刚获取的token马上失效
*/
static private synchronized String getNewToken() throws IOException {
// 通过获取token的接口,同步请求接口
String newToken = "";
//....
return newToken;
}
}
添加拦截器
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(3000, TimeUnit.SECONDS)
.writeTimeout(3000, TimeUnit.SECONDS)
.addInterceptor(new TokenInterceptor())//添加获取token的拦截器
.build();