OkHttp中,我们对请求报文和返回报文的处理都是在拦截器中进行的,所以熟悉OkHttp中的各个拦截器以及它们是怎样的处理流程是理解OkHttp的重点
拦截器链
首先,我们所最后得到的Response是通过这个函数得到的。
1 | Response result = getResponseWithInterceptorChain(); |
而这个函数当中,就定义了各个拦截器的处理位置,并把每个拦截器都加入到了拦截器链当中。
1 | Response getResponseWithInterceptorChain() throws IOException { |
我们可以看到拦截器的顺序大概是:
- 自定义的拦截器(可定义多个)
- retryAndFollowUpInterceptor
- BridgeInterceptor
- CacheInterceptor
- ConnectInterceptor
- 自定义networkInterceptors(可定义多个)
- CallServerInterceptor
我们来一个个看看各个拦截器都做了什么,或者说能做什么(自定义拦截器)
各个拦截器的作用
自定义拦截器
1 | OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() { |
自定义拦截器是对初始的请求报文进行最先的预处理,我们可以在请求报文中加入统一的Header,比如说可以加入Authorization的Header,这样在认证失效后可以进行自动重新认证。
retryAndFollowUpInterceptor
我们可以看到它的intercept分发如下所示:
1 | @Override public Response intercept(Chain chain) throws IOException { |
其实顾名思义,我们可以从它的名字就看出来它的作用就是在失败时进行重试,以及遇到重定向后决定是否进行后续请求。
BridgeInterceptor
BridgeInterceptor所做的事情很多,它可以说是将一些必要的Header都加入到了请求报文当中。它的Intercept方法如下所示:
1 | @Override public Response intercept(Chain chain) throws IOException { |
可以看到,BridgeInterceptor将请求报文的长度,以及能够接收传输的方法(分块),以及请求报文内容的格式等都加入了,需要特别注意的是,这里也加入了保持长连接 与 可接收压缩格式 的Header,在加入可接受压缩格式的Header的同时,它也在获得返回报文后对报文进行了解压,也就是说,如果返回报文没有经过BridgeInterceptor的话,我们看到的将是压缩的响应报文。
CacheInterceptor
CacheInterceptor可以说是在真正地进行网络请求时的最后一重关卡,如果发现当前请求报文所请求的数据已经请求过了并存放在Cache当中,那么将会直接使用Cache(缓存)中的数据进行返回,它的Intercept方法如下:
1 | @Override public Response intercept(Chain chain) throws IOException { |
在这里我们需要注意的是,我们如果需要让CacheInterceptor发挥作用,那么我们必须手动配置Cache,且OkHttp中存在着两个Cache(Cache与InteralCache),只能选择配置其中的一个。
ConnectInterceptor
在ConnectInterceptor中,会开始建立真正的连接,具体是TCP连接还是TLS连接则需要看具体的网络请求。
它的Intercept方法如下:
1 | @Override public Response intercept(Chain chain) throws IOException { |
networkInterceptors(自定义)
这里也是添加自定义的拦截器,添加方式如下:
1 | .addNetworkInterceptor(new Interceptor() { |
与之前的自定义拦截器不同的是,这个拦截器可以看到最完整的请求报文与最原始的响应报文
CallServerInterceptor
这个拦截器是请求报文的最后一个拦截器,也是响应报文的第一个拦截器,它是真正与服务器进行交互的拦截器,它负责请求与响应的I/O工作,Intercept方法如下所示:
1 | @Override public Response intercept(Chain chain) throws IOException { |