okhttp 責(zé)任鏈攔截器

攔截器
  • 用戶自定義的攔截器
    • 應(yīng)用攔截器 在所有攔截器的前面
    • 網(wǎng)絡(luò)攔截器 在 RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor攔截器的后面,CallServerInterceptor攔截器的后面

1、 RetryAndFollowUpInterceptor

連接失敗后進(jìn)行重試、對(duì)請(qǐng)求結(jié)果跟進(jìn)后進(jìn)行重定向

  • 如果通過(guò) RouteException
    • 通過(guò)單個(gè)路由出現(xiàn)了多次鏈接都失敗以后出現(xiàn)此異常
    • 根據(jù) recover 判斷是否需要重連
  • 如果沒(méi)有添加應(yīng)用攔截器,那么RetryAndFollowUpInterceptor就是第一個(gè)攔截器,主要功能是判斷是否需要重試和重定向。
    如果請(qǐng)求階段發(fā)生了IOException,就會(huì)通過(guò)recover方法判斷是進(jìn)行連接重試。
    重定向發(fā)生在重試的判定之后,如果不滿足重試的條件,還需要進(jìn)一步調(diào)用followUpRequest根據(jù)Response 的響應(yīng)碼(
    當(dāng)然,如果直接請(qǐng)求失敗,Response都不存在就會(huì)拋出異常)判斷是否重定向;followup最大發(fā)生次數(shù)20次。

2、 BridgeInterceptor

BridgeInterceptor,連接應(yīng)用程序和服務(wù)器的橋梁,我們發(fā)出的請(qǐng)求會(huì)經(jīng)過(guò)它的處理才能發(fā)給服務(wù)器,
比如設(shè)置請(qǐng)求內(nèi)容的長(zhǎng)度,編碼,gzip壓縮,cookie等;獲取響應(yīng)后保存cookie、解壓等操作。
相對(duì)比較簡(jiǎn)單。

  • 對(duì)用戶構(gòu)建的Request進(jìn)行添加或者刪除相關(guān)頭部信息,以轉(zhuǎn)化成能夠真正進(jìn)行網(wǎng)絡(luò)請(qǐng)求的Request。
  • 將符合網(wǎng)絡(luò)請(qǐng)求規(guī)范的Request交給下一個(gè)攔截器處理,并獲取Response。
  • 如果響應(yīng)體經(jīng)過(guò)了gzip壓縮,那就需要解壓,再構(gòu)建成用戶可用的Response并返回。

首先,chain.proceed()執(zhí)行前,對(duì)請(qǐng)求頭進(jìn)行補(bǔ)全,補(bǔ)全請(qǐng)求頭如下:

請(qǐng)求頭 說(shuō)明
Content-Type 請(qǐng)求體類型,如:application/x-www-form-urlencoded
Content-Length/Transfer-Encoding 請(qǐng)求體解析方式
Host 請(qǐng)求的主機(jī)站點(diǎn)
Connection: Keep-Alive 保持長(zhǎng)連接
Accept-Encoding: gzip 接受響應(yīng)支持gzip壓縮
Cookie cookie身份辨別
User-Agent 請(qǐng)求的用戶信息,如:操作系統(tǒng)、瀏覽器等

先把響應(yīng)header中的cookie存入cookieJar(如果有),在下次請(qǐng)求則會(huì)讀取對(duì)應(yīng)的數(shù)據(jù)設(shè)置進(jìn)入請(qǐng)求頭,默認(rèn)的CookieJar不提供實(shí)現(xiàn),需要我們?cè)诔跏蓟疧khttpClient時(shí)配置我們自己的cookieJar。
如果使用gzip返回的數(shù)據(jù),則使用GzipSource包裝便于解析

3、 CacheInterceptor

CacheInterceptor,在發(fā)出請(qǐng)求前,先判斷是否命中緩存,如果命中則可以不請(qǐng)求,直接使用緩存的響應(yīng)(默認(rèn)只會(huì)對(duì)Get請(qǐng)求進(jìn)行緩存);如果未命中則進(jìn)行網(wǎng)絡(luò)請(qǐng)求,并將結(jié)果緩存,等待下次請(qǐng)求被命中。

大概梳理一下步驟:

  • 從緩存中獲取對(duì)應(yīng)請(qǐng)求的響應(yīng)緩存
  • 創(chuàng)建CacheStrategy,創(chuàng)建時(shí)會(huì)判斷是否能夠使用緩存,在CacheStrategy中有兩個(gè)成員:networkRequest和cacheResponse。他們有如下組合進(jìn)行判斷:
networkRequest cacheResponse 說(shuō)明
Null Null 網(wǎng)絡(luò)請(qǐng)求、緩存 都不能用,okhttp直接返回504
Null Not Null 直接使用緩存
Not Null Null 向服務(wù)器發(fā)起請(qǐng)求
Not Null Not Null 向服務(wù)器發(fā)起請(qǐng)求,若得到響應(yīng)碼為304(無(wú)修改),則更新緩存響應(yīng)并返回
  • 交給下一個(gè)責(zé)任鏈繼續(xù)處理
  • 后續(xù)工作,返回304則用緩存的響應(yīng);否則使用網(wǎng)絡(luò)響應(yīng)并緩存本次響應(yīng)(只緩存Get請(qǐng)求的響應(yīng))
  • 緩存攔截器中判斷使用緩存或者請(qǐng)求服務(wù)器都是通過(guò)CacheStrategy判斷。分析CacheStrategy前我們先來(lái)了解下Http的緩存機(jī)制,以便更好的理解:
okhttp_cache.png
okhttp_cache_2.png

4、 ConnectInterceptor

這個(gè)攔截器主要的作用就是負(fù)責(zé)從連接池獲取健康的連接(判斷連接的 Socket 傳輸通道是否可用),如果在連接池中沒(méi)有找到符合復(fù)用的連接(除了主機(jī)地址之外的信息必須要全部匹配,例如 DNS、代理、協(xié)議、證書),那么就會(huì)使用路由再找一遍(路由的結(jié)構(gòu)是一個(gè)代理服務(wù)器的地址 + DNS 中的一個(gè) IP 地址),如果還是沒(méi)有,那么會(huì)直接創(chuàng)建一個(gè)新的連接對(duì)象并進(jìn)行三次握手,再將這個(gè)新的連接對(duì)象添加到連接池中,最后將可復(fù)用的連接返回回去

4、 CallServerInterceptor

CalllServerInterceptor是最后一個(gè)攔截器了,前面的攔截器已經(jīng)完成了socket連接和tls連接,那么這一步就是傳輸http的頭部和body數(shù)據(jù)了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容