2020-07-14 OkHttp拦截器 - 应用拦截器和网络拦截器的区别
OkHttp的拦截器分为应用拦截器和网络拦截器。一般来说,一个请求会先经过应用拦截器,再进入内核,然后是网络拦截器。这样的调用关系形成了一个责任链,有点类似递归调用。
应用拦截器主要关注发起的请求和最终得到的结果,它不涉及重定向或重试等中间响应。应用拦截器可以拦截Chain.proceed()或多次调用Chain.proceed()。相对而言,网络拦截器关注于网络调用模块,可以处理重定向和重试的中间响应。如果应用拦截器选择短路回应并返回缓存,则网络拦截器将不会被调用。
OkHttp源码分析:五大拦截器详解
主要完成两件事:重试与重定向。
重试与重定向拦截器主要处理Response。可以看到RouteException和IOException都调用了recover,返回true表示允许重试。在允许重试的情况下,会不断调用realChain.proceed,从而完成重试过程。
接着看重定向的处理概要。
在重试和重定向的判断中,首先会用RetryAndFollowUpInterceptor来决定是否需要重试。若出现RouteException或IOException,则通过recover方法判断是否进行重试。重定向则在重试判定后进行,依据Response的响应码调用followUpRequest进行重定向。这就是重定向的总结。
补全请求头:
BridgeInterceptor是连接应用程序和服务器的桥梁,它的主要功能是补全请求头,将请求转换为符合网络规范的Request。接收到响应后:
- 1. 保存Cookie,以便下次请求时读取相应的cookie数据。
- 2. 如果使用gzip返回的数据,则使用GzipSource包裹以便解析。
缓存拦截器主要处理缓存,前提是基于GET请求的。我们可以通过okHttpClient.cache(cache)来设置。缓存拦截器的处理流程包括:
- 从缓存中取出对应请求的响应缓存。
- 通过CacheStrategy决定使用缓存还是发起网络请求。
若networkRequest存在,则优先发起网络请求,否则使用cacheResponse缓存,如果均不存在则请求失败。
如果最终决定不能使用缓存,需要发起网络请求,那么将进入下一个拦截器ConnectInterceptor。
StreamAllocation对象是在第一个拦截器RetryAndFollowUpInterceptor中初始化的,负责请求、连接与数据流之间的关系,确保网络通信的有效性。
StreamAllocation对象有两个关键角色:
- RealConnection:真正的连接由ConnectionPool管理。
- 创建和建立连接的过程包括:streamAllocation.newStream -> findHealthyConnection -> findConnection。
在findConnection中:
- 1. 如果StreamAllocation的连接可以复用,则进行复用。
- 2. 如果不能复用,则从连接池获取RealConnection对象。
- 3. 如果连接池没有,则新建一个RealConnection对象。
- 4. 使用RealConnection的connect()方法初始化请求。
- 5. 将RealConnection对象放入连接池以便下次复用。
小结:
ConnectInterceptor拦截器从拦截器链中获取StreamAllocation对象,并使用streamAllocation.newStream方法创建HttpCodec对象,用于编解码HTTP请求和响应。
CallServerInterceptor负责HTTP协议报文的封装和解析,流程如下:
- 1. 获取HttpCodec、StreamAllocation、RealConnection对象。
- 2. 调用httpCodec.writeRequestHeaders(request)写入请求头。
- 3. 判断是否有请求体,对应请求头携带Expect:100-continue。
- 4. 结束请求通过httpCodec.finishRequest()。
- 5. 通过responseBuilder构建Response。
OkHttp3拦截器 - 应用拦截器和网络拦截器的区别
在OkHttp3中,拦截器分为应用拦截器和网络拦截器,两者有显著区别。在使用时务必注意,以免引发不必要的麻烦。接下来,我将详细说明这两个拦截器的差异。
根据前面的内容,我们可以制作Application Interceptor和Network Interceptor的执行流程图。