2020-07-14 OkHttp拦截器 - 应用拦截器和网络拦截器的区别

OkHttp的拦截器分为应用拦截器和网络拦截器。一般来说,一个请求会先经过应用拦截器,再进入内核,然后是网络拦截器。这样的调用关系形成了一个责任链,有点类似递归调用。

应用拦截器主要关注发起的请求和最终得到的结果,它不涉及重定向或重试等中间响应。应用拦截器可以拦截Chain.proceed()或多次调用Chain.proceed()。相对而言,网络拦截器关注于网络调用模块,可以处理重定向和重试的中间响应。如果应用拦截器选择短路回应并返回缓存,则网络拦截器将不会被调用。

OkHttp源码分析:五大拦截器详解

主要完成两件事:重试与重定向。

重试与重定向拦截器主要处理Response。可以看到RouteException和IOException都调用了recover,返回true表示允许重试。在允许重试的情况下,会不断调用realChain.proceed,从而完成重试过程。

2020-07-14 OkHttp拦截器 - 应用拦截器和网络拦截器的区别,OkHttp3拦截器 - 应用拦截器和网络拦截器的区别

接着看重定向的处理概要。

在重试和重定向的判断中,首先会用RetryAndFollowUpInterceptor来决定是否需要重试。若出现RouteException或IOException,则通过recover方法判断是否进行重试。重定向则在重试判定后进行,依据Response的响应码调用followUpRequest进行重定向。这就是重定向的总结。

补全请求头:

BridgeInterceptor是连接应用程序和服务器的桥梁,它的主要功能是补全请求头,将请求转换为符合网络规范的Request。接收到响应后:

  • 1. 保存Cookie,以便下次请求时读取相应的cookie数据。
  • 2. 如果使用gzip返回的数据,则使用GzipSource包裹以便解析。

缓存拦截器主要处理缓存,前提是基于GET请求的。我们可以通过okHttpClient.cache(cache)来设置。缓存拦截器的处理流程包括:

  1. 从缓存中取出对应请求的响应缓存。
  2. 通过CacheStrategy决定使用缓存还是发起网络请求。

若networkRequest存在,则优先发起网络请求,否则使用cacheResponse缓存,如果均不存在则请求失败。

如果最终决定不能使用缓存,需要发起网络请求,那么将进入下一个拦截器ConnectInterceptor。

StreamAllocation对象是在第一个拦截器RetryAndFollowUpInterceptor中初始化的,负责请求、连接与数据流之间的关系,确保网络通信的有效性。

StreamAllocation对象有两个关键角色:

  1. RealConnection:真正的连接由ConnectionPool管理。
  2. 创建和建立连接的过程包括:streamAllocation.newStream -> findHealthyConnection -> findConnection。

在findConnection中:

2020-07-14 OkHttp拦截器 - 应用拦截器和网络拦截器的区别,OkHttp3拦截器 - 应用拦截器和网络拦截器的区别

  • 1. 如果StreamAllocation的连接可以复用,则进行复用。
  • 2. 如果不能复用,则从连接池获取RealConnection对象。
  • 3. 如果连接池没有,则新建一个RealConnection对象。
  • 4. 使用RealConnection的connect()方法初始化请求。
  • 5. 将RealConnection对象放入连接池以便下次复用。

小结:

ConnectInterceptor拦截器从拦截器链中获取StreamAllocation对象,并使用streamAllocation.newStream方法创建HttpCodec对象,用于编解码HTTP请求和响应。

CallServerInterceptor负责HTTP协议报文的封装和解析,流程如下:

2020-07-14 OkHttp拦截器 - 应用拦截器和网络拦截器的区别,OkHttp3拦截器 - 应用拦截器和网络拦截器的区别

  • 1. 获取HttpCodec、StreamAllocation、RealConnection对象。
  • 2. 调用httpCodec.writeRequestHeaders(request)写入请求头。
  • 3. 判断是否有请求体,对应请求头携带Expect:100-continue。
  • 4. 结束请求通过httpCodec.finishRequest()。
  • 5. 通过responseBuilder构建Response。

OkHttp3拦截器 - 应用拦截器和网络拦截器的区别

在OkHttp3中,拦截器分为应用拦截器和网络拦截器,两者有显著区别。在使用时务必注意,以免引发不必要的麻烦。接下来,我将详细说明这两个拦截器的差异。

根据前面的内容,我们可以制作Application Interceptor和Network Interceptor的执行流程图。