它可以实现网络监听、请求以及响应重写、请求失败重试等功能.
拦截器的作用
- 拦截器可以一次性对所有请求的返回值进行修改
- 拦截器可以一次性对请求的参数和返回的结果进行编码,比如统一设置为UTF-8.
- 拦截器可以对所有的请求做统一的日志记录,不需要在每个请求开始或者结束的位置都添加一个日志操作。
- 其他需要对请求和返回进行统一处理的需求…
拦截器的分类
分为2个:APP层面的拦截器和网络请求层面的拦截器
addNetworkInterceptor和addInterceptor两个方法同样是添加拦截器,addNetworkInterceptor添加的是网络拦截器,在网络畅通的时候会调用,而addInterceptor则都会调用
Application Interceptors
调用addInterceptor()在OkHttpClient.Builder链式代码中注册一个application拦截器。
- 无法操作中间的响应结果,比如当URL重定向发生以及请求重试等,只能操作客户端主动第一次请求以及最终的响应结果。
- 在任何情况下只会调用一次,即使这个响应来自于缓存。
- 可以监听观察这个请求的最原始未经改变的意图(请求头,请求体等),无法操作OkHttp为我们自动添加的额外的请求头,比如If-None-Match。
- 允许short-circuit (短路)并且允许不去调用Chain.proceed()。(这句话的意思是Chain.proceed()不需要一定要去调用服务器请求,但是必须还是需要返回Respond实例。那么实例从哪里来?答案是缓存。如果本地有缓存,可以从本地缓存中获取响应实例返回给客户端。这就是short-circuit (短路)的意思。。囧)
- 允许请求失败重试以及多次调用Chain.proceed()。
Network Interceptors
调用的是addNetworkInterceptor()
- 允许操作中间响应,比如当请求操作发生重定向(拦截被执行了两次)或者重试等。
- 不允许调用缓存来short-circuit (短路)这个请求。(意思就是说不能从缓存池中获取缓存对象返回给客户端,必须通过请求服务的方式获取响应,也就是Chain.proceed())
- 可以监听数据的传输
- 允许Connection对象装载这个请求对象。(Connection是通过Chain.proceed()获取的非空对象)
上面这张图,有三种拦截器:应用拦截器、网络拦截器和OkHttp core核心代码中的拦截器。application生成request,通过应用拦截器对其做一系列处理后给OkHttp core中的拦截器,之后通过网络拦截器再做处理,最终访问到服务端返回response,经过网络拦截器处理response,再经过OkHttp core的拦截器处理,最终交给应用拦截器处理,返回给应用。
重写请求
拦截器可以添加、移除或者替换请求头。甚至在有请求主体时候,可以改变请求主体。
重写响应
和重写请求相似,拦截器可以重写响应头并且可以改变它的响应主体。相对于重写请求而言,重写响应通常是比较危险的一种做法,因为这种操作可能会改变服务端所要传递的响应内容的意图。