RetryAndFollowUpInterceptor
RetryAndFollowUpInerceptor 负责了 HTTP 请求的重定向功能。
HTTP 中的重定向
HTTP 协议提供了一种重定向的功能,它通过由服务器返回特定格式的响应从而触发客户端的重定向。其对应的 Response Code 格式为 3XX,并且会在 Response Header 的 Location 字段中放入新的 URL,这样我们客户端就可以根据该 Location 字段所指定的 URL 重新请求从而得到需要的数据。
重定向与服务器转发的区别
- 重定向是客户端行为,而服务器转发则是服务端行为
- 重定向我们的客户端发出了多次请求,而转发我们的客户端只发出了一次请求。
- 重定向的控制权在客户端,转发的控制权在服务端。
1 | public Response intercept(Chain chain) throws IOException { |
- 调用 chain.proceed 方法进行请求获取 Response
- 若出现其他未知的异常,则通过抛出异常释放资源
- 在本次 Response 中设置上一次的 Response priorResponse,且body为空
- 根据 Response 中的 response code 进行重定向,调用 followUpRequest 方法获取重定向后的 request followUp
- 若重定向后的 followUp 为 null,说明不再需要重定向,停止 timeout 计时并返回 Response
- 若重定向超过指定次数(默认 20 次),则抛出异常。
- 若仍未返回,则需要下一次重定向,对下一次的 request 等变量进行赋值。
1 | private Request followUpRequest(Response userResponse, Route route) throws IOException { |
BridgeInterceptor
BridgeInterceptor 的名字取的非常形象,它就像一座桥梁,连接了用户与服务器。在用户向服务器发送请求时,它会把用户所构建的请求转换为向服务器请求的真正的 Request,而在服务器返回了响应后,它又会将服务器所返回的响应转换为用户所能够使用的 Response。
1 | public Response intercept(Chain chain) throws IOException { |
可以看到,这里主要对 Header 进行处理,将一些原来 request 中的 Header 进行处理后设置进了新 request,并用其进行请求。其中若调用者未设置 Accept-Encoding,则它会默认设置 gzip。
而在对 response 处理时,若之前设置了 gzip,则进行 gzip 解压。这种自动解压会自动将 Content-Length、Content-Encoding 字段从 Header 中移除。
CacheInterceptor
CacheInterceptor 主要负责了对缓存的读取以及更新。
1 | public Response intercept(Chain chain) throws IOException { |
- 尝试从缓存中获取了缓存的 response
- 根据 当前时间、request、缓存的response 构建缓存策略。
- 若缓存策略不能使用网络(networkRequest == null),且无缓存(cacheResponse == null),则直接请求失败。
- 若缓存策略不能使用网络,由于前面有判断所以可以确定有缓存,直接构建缓存的 response 并返回。
- 调用 chain.proceed 网络请求获取 response
- 对 code 304 作出处理,结合本地及网络返回数据构建 response 并返回
- 构建网络请求的所获得的 response ,并且由于该网络请求并未进行过缓存,进行缓存并返回结果
ConnectInterceptor
主要用来建立连接。
1 | public final class ConnectInterceptor implements Interceptor { |
CallServerInterceptor
负责请求网络。
1 | public Response intercept(Chain chain) throws IOException { |
- 写入Request Header
- 写入Request Body
- 读取Response Header
- 读取Response Body