第一種方案
通過okhttp提供的Authenticator接口,但是只有HTTP返回碼為401時才會觸發(fā)。此種方式局限性很大,要求后臺設(shè)計必須符合規(guī)范枫笛。在實際項目中不可能完美實現(xiàn)。此種方式不做詳解刚照,百度很多刑巧。
第二種方案
根據(jù)和后端協(xié)商好的返回碼處理刷新token步驟。代碼如下;
public class TokenInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder request = chain.request().newBuilder();
//添加默認(rèn)的Token請求頭
request.addHeader("Cookie", UserInfo.getInstance().getPhpSessionId());
Response proceed = chain.proceed(request.build());
okhttp3.MediaType mediaType = proceed.body().contentType();
//如果token過期 再去重新請求token 然后設(shè)置token的請求頭 重新發(fā)起請求 用戶無感
String content = proceed.body().string();
if (isTokenExpired(content)) {
String newToken = getNewToken();
UserInfo.getInstance().setPhpSessionId(newToken);
//使用新的Token啊楚,創(chuàng)建新的請求
Request newRequest = chain.request().newBuilder()
.addHeader("Cookie", newToken)
.build();
return chain.proceed(newRequest);
}
return proceed.newBuilder()
.body(okhttp3.ResponseBody.create(mediaType, content))
.build();
}
private String getNewToken() {
// 通過一個特定的接口獲取新的token吠冤,此處要用到同步的retrofit請求
IndexService service = IndexService.Builder.getServer();
Call<BaseObjResult<UserBean>> call = service.getToke(
UserInfo.getInstance().getPhone(),
UserInfo.getInstance().getPwd(),
0);
//要用retrofit的同步方式
BaseObjResult<UserBean> newToken = null;
try {
newToken = call.execute().body();
} catch (IOException e) {
e.printStackTrace();
}
return newToken.getResult().getPHPSESSID();
}
/**
* 根據(jù)Response,判斷Token是否失效
*
* @return
*/
private boolean isTokenExpired(String resultStr) {
RequestCode requestCode = new Gson().fromJson(resultStr, RequestCode.class);
//err==3 token過期
if (requestCode.getErr() == 3) {
LogUtils.e("Token登錄過期了");
ToastUtils.showShortSafe("Token登錄過期了");
return true;
}
return false;
}
class RequestCode {
private int err;
private String msg;
public int getErr() {
return err;
}
public void setErr(int err) {
this.err = err;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
}
使用方式
okBuilder.addInterceptor(new TokenInterceptor()); //請求過期更換token