拦截器Interceptor总结
目录介绍
1.拦截器简介
2.拦截器的种类
3.拦截器种类选择
4.解决实际问题:如何避免登录过期问题?
好消息
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong211/YCBlogs
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!
1.拦截器简介
官方定义
Interceptors area powerful mechanism that can monitor, rewrite, and retry calls.
拦截器可以用来转换,重试,重写请求的机制。
OkHttp的 Interceptor 就如同名称「拦截器」一样,拦截你的 Request 做一些你想做的事情再送出去。例如:
1.自动加上使用者目前使用的语言送出去取得对应语言的回传内容。
2.将 Request 计算出这个 Request 的 sigunature 再附加上送出去。
拦截器是 OkHttp 提供的对 HTTP 请求和响应进行统一处理的强大机制。拦截器在实现和使用上类似于 Servlet 规范中的过滤器。多个拦截器可以链接起来,形成一个链条。拦截器会按照在链条上的顺序依次执行。 拦截器在执行时,可以先对请求的 Request 对象进行修改;再得到响应的 Response 对象之后,可以进行修改之后再返回。
Interceptor 接口只包含一个方法 intercept,其参数是 Chain 对象。Chain 对象表示的是当前的拦截器链条。通过 Chain 的 request 方法可以获取到当前的 Request 对象。在使用完 Request 对象之后,通过 Chain 对象的 proceed 方法来继续拦截器链条的执行。当执行完成之后,可以对得到的 Response 对象进行额外的处理。
2.拦截器种类
在 okHttp 中分成两种:
Application Interceptor
Network Interceptor Application Interceptor 是会可以被 cache 起来的
OkHttp 中的拦截器分成应用和网络拦截器两种
应用拦截器对于每个 HTTP 响应都只会调用一次,可以通过不调用 Chain.proceed 方法来终止请求,也可以通过多次调用 Chain.proceed 方法来进行重试。
网络拦截器对于调用执行中的自动重定向和重试所产生的响应也会被调用,而如果响应来自缓存,则不会被调用。
添加应用和网络拦截器
- client.interceptors().add(new LoggingInterceptor()); //添加应用拦截器
- client.networkInterceptors().add(new LoggingInterceptor()); //添加网络拦截器
3.拦截器选择
1.应用拦截器
不需要担心中间过程的响应,如重定向和重试.
总是只调用一次,即使HTTP响应是从缓存中获取.
观察应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match.
允许短路而不调用 Chain.proceed(),即中止调用.
允许重试,使 Chain.proceed()调用多次.
2.网络拦截器
能够操作中间过程的响应,如重定向和重试.
当网络短路而返回缓存响应时不被调用.
只观察在网络上传输的数据.
携带请求来访问连接.
4.解决实际问题:如何避免登录过期问题?
public class NewSeedInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
String name = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.name, Constants.NAME);
String pwd = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.pwd, Constants.PWD);
String smsCode = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.code, Constants.CODE);
String from = SPUtils.getInstance(Constants.NEW_SEED).getString(Constants.uForm, "0");
int uFrom = Integer.parseInt(from);
Request req = chain.request();
Request request = req.newBuilder()
.addHeader("Cookie", ApiConstants.COOKIE + Constants.sid)
.addHeader("apptype", "2")
.build();
Response response = chain.proceed(request);
if (response.code()==200 && response.body()!=null) {
Constants.string = response.body().string();
if(AppCommentUtils.isGoodJson(Constants.string)){
if (Constants.string.contains("{") && Constants.string.contains("}") && !Constants.string.contains("<html>")) {
int code = new Gson().fromJson(Constants.string, BaseBean.class).getCode();
if (code == -1) {
if (name != null && name.length()>0 && pwd != null && pwd.length()>0) {
if (uFrom == 0) { //手机号直接登录
Constants.sid = NewSeedUtils.getNewSid(name, pwd, uFrom + "");
Log.i("sid值手机",Constants.sid+"");
} else if (uFrom == 11) { //sms登录
Constants.sid = NewSeedUtils.getNewSidSms(name, smsCode, uFrom + "");
Log.i("sid值手机",Constants.sid+"");
} else { //第三方登录
Constants.sid = NewSeedUtils.getNewSidOther(name, pwd, uFrom + "");
Log.i("sid值第三方",Constants.sid+"");
}
}
}
}
}
}
return response;
}
}