众所周知,当前处理网络模块最好用的应该还是Retrofit+okhttp的处理,但是在我现在正在做的项目中出现了一个问题,问题如下:
本项目服务器端验证登录是否失效使用了微服务,对微服务没啥理解的说明本博客暂时不适合于你所碰到的问题,因此可以绕道了。验证方面使用了微服务,会导致的问题就是,当你登录时或者调用任意一个接口时token已经处于失效状态的情况下,他不会给你返回任何数据,而是会给你报401,我们都知道,对于前端来讲,状态永远只关心两个,一个是200另一个就是其他,而Retrofit+okhttp架构很忠实的遵循了上面的原则,因此你得不到任何信息。所以我在项目中做了如下处理,以达到伪踢下线的功能,话不多说,直接上代码:
public class HttpResult<T> {
public String resp_code;
public String resp_msg;
public T datas;
}
public class ResponseInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
ResponseBody responseBody = response.body();
if (responseBody != null) {
String json = responseBody.string();
String newChars = ":null";
String emptyString = ":\"\"";
if (json.contains(emptyString)) {
json = json.replace(emptyString, newChars);
}
String emptyArray = ":[]";
if (json.contains(emptyArray)) {
json = json.replace(emptyArray, newChars);
}
String emptyObject = ":{}";
if (json.contains(emptyObject)) {
json = json.replace(emptyObject, newChars);
}
if (response.code() != 200 && StringUtil.checkStr(json)) {
HttpResult result = new Gson().fromJson(json, HttpResult.class);
if (result != null && StringUtil.checkStr(result.resp_code) && !result.resp_code.equals("0")) {
switch (result.resp_code) {
case "401":
SharePreferenceUtil.saveToken(App.context, "");
LoginEvent event = new LoginEvent();
event.type = 1;
event.msg = "登录失效";
EventBus.getDefault().post(event);
break;
}
}
if (StringUtil.checkStr(result.resp_msg)) {
Toa.showShort(result.resp_msg);
}
}
MediaType contentType = responseBody.contentType();
ResponseBody body = ResponseBody.create(contentType, json);
return response.newBuilder().body(body).build();
}
return response;
}
}
可以看到在
if (response.code() != 200 && StringUtil.checkStr(json)) {}
这个判断中,我们做了如上处理,首先,当微服务判断为token失效时,先让后台返回一个401的json,里面注明信息,因为401会被RxIava当做error,所以此时我们的View层是完全拿不到数据的,只能在拦截器中做状态处理(我是这么做的,如有未使用RxJava的,可能也不会出现这个问题)当code伪401时,我首先把本地缓存的token清除,然后使用EventBus发一个通知,然后在BaseActivity中去做一些登录失效的处理。我的处理是跳转到一个全透明的Activity中,然后内置一个dialog,去提示用户登录失效或已经被踢下线。
总结
上述问题只适用于碰到该问题的同学,若对拦截器不熟练的请参考:https://www.jianshu.com/p/11fe36b2021e 这一篇里面我详细介绍过拦截器的使用方法。若本文对您有用,请帮忙点个赞,同时,有任何疑问可以直接回复或站内私信我,谢谢观看!
网友评论