源码解读系列(三)网络框架之OkHttp3(下)--拦截器

首先套用官网的一句话来描述拦截器的作用:

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.
拦截器是一个功能强大的机制,可以监视、重写和重试调用。

我们首先总结一下okhttp默认添加的几个拦截器的作用

1、RetryAndFollowUpInterceptor:重试和followup拦截器

followup就是跟进的意思
这个拦截器的作用是负责请求的重定向,当一个请求由于各种原因失败了,如果是因为路由或者连接异常导致的则尝试请求恢复连接,如果是因为响应码导致的失败则会重新发起一次请求,比如返回了3xx、307、407等就会重新发起一次请求。同时这个拦截器负责管理okhttp的连接池的复用以及请求完成后释放连接的操作。多路复用的是http2的特性,而okhttp是支持http2的。

2、BridgeInterceptor:桥接拦截器

处理请求体和响应体,把用户构造的请求转换成发送给服务器的请求,把服务器返回的响应体处理成对用户友好的返回值。
1、对请求体的处理主要是添加一些请求头,比如添加User-Agent、Content-Type、Content-Length、Keep-Alive以及如果设置了cookieJar当Cookie为空的时候创建Cookie等
2、对响应体的处理主要是将返回的数据进行gzip解压,去掉一些头信息比如Content-Encoding、Content-Length以及如果设置了cookieJar则保存Cookie等

3、CacheInterceptor:缓存拦截器

首先http的缓存分成强制缓存和对比缓存两种,强制缓存就是当本地缓存有效的时候使用本地缓存,不再发起网络请求,对比缓存就是总会发起网络请求,如果请求的结果和上一次一样那么就返回304,但是不会返回响应体,这个时候就要从本地缓存中取数据,如果请求结果和上一次不一样,那么就会返回新的数据。

所以okhttp的缓存也是从这两个方面来进行的
1、首先判断本地是否有缓存,如果有再判断是否有缓存策略,缓存是否过期,如果没有过期那么就直接使用本地缓存,如果过期了就请求网络
2、如果服务器返回了304那么还是会继续使用本地缓存,如果没有返回304则使用服务器返回的新数据并把它加入到缓存里去

4、ConnectInterceptor 连接拦截器
/** Opens a connection to the target server and proceeds to the next interceptor. */
public final class ConnectInterceptor implements Interceptor {
  public final OkHttpClient client;

  public ConnectInterceptor(OkHttpClient client) {
    this.client = client;
  }

  @Override public Response intercept(Chain chain) throws IOException {
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    Request request = realChain.request();
    Transmitter transmitter = realChain.transmitter();

    // We need the network to satisfy this request. Possibly for validating a conditional GET.
    boolean doExtensiveHealthChecks = !request.method().equals("GET");
    Exchange exchange = transmitter.newExchange(chain, doExtensiveHealthChecks);

    return realChain.proceed(request, transmitter, exchange);
  }
}

创建和服务器的连接,并执行下一个拦截器,下一个拦截器也就是CallServerInterceptor请求拦截器

5、CallServerInterceptor 请求拦截器

负责网络连接的最后一步,发起网络请求进行数据交换。
主要做了如下几件事:
1、写入header,如果请求头是100-continue那么就只发送请求头询问服务器是否同意接受数据,然后根据后台的返回值判断是否继续发送数据给服务器。如果判断服务器同意接受数据再写入请求体并发起请求。
2、写入请求体,使用的是okio进行操作,okio是okhttp对io操作的一层封装。
3、写入完成后完成请求
4、得到响应体
5、返回响应体

以上就是okhttp的几个默认添加的拦截器的作用啦

另外okhttp遍历默认拦截器和用户自定义拦截器的核心方法是RealInterceptorChain的proceed方法

其核心代码是这几句:

    // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
        index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);

1、构建新的RealInterceptorChain对象的时候index值加1,也就是在List interceptors;这个List中取出下一个拦截器来构建一个新的RealInterceptorChain对象,并把这个RealInterceptorChain对象传递给当前拦截器的拦截方法interceptor.intercept(next)
2、执行当前拦截器拦截方法,执行完成后会调用传进来的RealInterceptorChain对象的proceed方法
3、在RealInterceptorChain的proceed方法中又会重复执行上述1步骤。
4、这样就达到了遍历拦截器的目的,其实这是一个责任链模式,每个拦截器负责完成自己的任务,并把责任传递给下一个拦截器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值