OkHttp中的Interceptors
getResponseWithInterceptorChain()
继续说getResponseWithInterceptorChain()
方法
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
这个方法的作用是将你自己配置的Interceptor和OkHttp默认给我加上的Interceptor放在一个List中,然后将List作为参数创建一个RealInterceptorChain
对象,并调⽤chain.proceed(request)
来发起请求和获取响应。
Interceptor的原理
因为网络请求的过程太复杂了,OkHttp并没有把所有的东西都写在了一起,而是拆成了几个部分,每个部分就是一个Interceptor, 多个Interceptor组成了Interceptor.chain. Interceptor主要对Request做一些预处理和对Response后续处理.
Interceptor是怎么工作的?
先说下基本用法吧
OkHttpClient client = new OkHttpClient().newBuilder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//对request做一些预处理
Response response = chain.proceed(request);
//对response做一下后续处理
return response;
}
}).build();
执行请求的时候,会执行chain.porcess(originalRequest)
,RealInterceptorChains是Interceptor.chain的实现类,RealInterceptorChains 会从 List interceptors中的最后一个添加Interceptor开始依次调用intercept()方法, 对originalRequest进行预处理,然后再调用chain.proceed(),把请求交给下一个Interceptor,直到第一个Interceptor,当然最后一个Interceptor做的是真正的网络请求,并拿到响应,然后从第一个Interceptor开始依次返回Response,依次进行对Response的后续处理直到最后一个.它相当于一个链式的递归,从最后一个开始递归调用Interceptor的intercept(),然后从第一个开始返回调用的结果
OkHttp自带的Interceptors
client.interceptors()
它是开发者使用 addInterceptor(Interceptor)
所设置的,它们会按照开发者的要求,在所有其他 Interceptor 处理理之前,进⾏行最早的预处理工作,以及在收到Response 之后,做最后的善后工作。如果你有统一的 header 要添加,可以在这里设置
RetryAndFollowUpInterceptor
它负责在请求失败时的重试,以及重定向的⾃动后续请求。它的存在,可以让重试和重定向对于开发者是无感知的
BridgeInterceptor
它负责一些不影响开发者开发,但影响 HTTP 交互的一些额外预处理。例如,Content-Length 的计算和添加、gzip 的⽀持(Accept-Encoding: gzip)、gzip 压缩数据的解包,都是发生在这里;
CacheInterceptor
它负责Cache的处理,把他它放在后面的网络交互相关 Interceptor 的前面的好处是,如果本地有了可用的 Cache,⼀个请求可以在没有发生实质网络交互的情况下就返回缓存结果,而完全不需要开发者做出任何的额外工作,让Cache 更加⽆感知;
ConnectInterceptor
它负责建立连接。在这里,OkHttp 会创建出网络请求所需要的TCP 连接(如果是 HTTP),或者是建立在 TCP 连接之上的 TLS 连接(如果是 HTTPS),并且会创建出对应的 HttpCodec 对象(⽤于编码解码 HTTP 请求)
client.networkInterceptors()
它是开发者addNetworkInterceptor(Interceptor)
所设置的,它们和使用addInterceptor(Interceptor)
创建的⼀样,但由于位置不同,所以这里创建的 Interceptor 会看到每个请求和响应的数据(包括重定向以及重试的一些中间请求和响应),并且看到的是完整原始数据,⽽不是没有加 Content-Length 的请求数据,或者Body 还没有被 gzip 解压的响应数据。多数情况,这个方法不需要被使用;
CallServerInterceptor
它负责实质的请求与响应的 I/O 操作,即往 Socket 写⼊请求数据,和从 Socket 读取响应数据。