1. 程式人生 > >OkHttp完全解析(六)攔截器

OkHttp完全解析(六)攔截器

攔截器是一種能夠監控,重寫,重試呼叫的強大機制。


呼叫chain.proceed(request)是每個攔截器實現的關鍵部分。這個看似簡單的方法是所有HTTP 工作發生的地方, 在這裡產生一個響應應答請求。

攔截器可以是鏈式的,假設你有一個壓縮攔截器和一個校驗攔截器,那麼需要決定資料是否被壓縮後進行校驗,或者是先校驗後壓縮。OkHttp採用列表的形式追蹤攔截器,攔截器會被有序呼叫。

   

7.1 應用攔截器

攔截器被註冊成為應用攔截器或者網路攔截器。下面通過上述定義的LoggingInterceptor來展示他們之間的不同。註冊一個應用攔截器通過呼叫OkHttpClient.interceptors()返回的List的add()方法完成。


URL http://www.publicobject.com/helloworld.txt重定向到

https://publicobject.com/helloworld.txt, OkHttp自動追蹤這個重定向過程。我們的應用攔截器會被呼叫一次,從chain.proceed()返回的響應是重定向後的響應。


可以看到,請求被重定向了,因為response.request().url()返回的結果跟request.url()返回的結果不一致。兩條日誌列印了不一樣的URL。

7.2 網路攔截器

註冊網路攔截器和註冊應用攔截器很類似。只是通過networkInterceptors()方法取代了interceptore()方法。


可以看到,請求被重定向了,因為response.request().url()返回的結果跟request.url()返回的結果不一致。兩條日誌列印了不一樣的URL。

7.2 網路攔截器

註冊網路攔截器和註冊應用攔截器很類似。只是通過networkInterceptors()方法取代了interceptore()方法。


執行這段程式碼時,程式碼運行了兩次,一次是初始化請求,一次是重定向請求。


網路請求也包含更多資料,比如OkHttp頭部中添加了Accept-Encoding:gzip請求頭通知響應壓縮。網路攔截器的Chain中有一個非空的連線可以用於詢問連線到web伺服器時使用的IP地址和TLS配置。

7.3 在應用攔截器和網路攔截器之間如何選擇

每個攔截器各有自己的優點

應用攔截器

        *不必要擔心響應和重定向之間的中間響應。

        *通常只調用一次,即使HTTP響應是通過快取提供的。

        *遵從應用層的最初目的。與OkHttp的注入頭部無關,如If-None-Match。

        *允許短路而且不呼叫Chain.proceed()。

        *允許重試和多次呼叫Chain.proceed()。

網路攔截器

        *允許像重定向和重試一樣操作中間響應。

        *網路發生短路時不呼叫快取響應。

        *在資料被傳遞到網路時觀察資料。

        *有權獲得裝載請求的連線。

7.4 重寫請求

通過攔截器可以新增,移除,替換請求頭。也可以改變請求的請求體。例如,在知道連線的web伺服器是否支援壓縮格式的情況下,可以使用應用攔截器新增請求體壓縮型別。


7.5 重寫響應

相對應地,攔截器可以重寫響應頭和改變響應體。這一點比重寫寫請求頭要危險,因為可能違反web伺服器的期望。

如果你處於一種比較糾結的狀態,並且準備處理結果,那麼重寫響應頭是解決問題的有效方法。例如,可以修復伺服器配置錯誤的Cache-Control響應頭是快取更高效。


典型情況,這樣做比在伺服器上處理這個問題要方便得多。

7.6 實用性

OkHttp攔截器在OkHttp2.2以後更優。不過,沒有OkUrlFactory,攔截器無法工作,基於OkHttp構建的框架有Retrofit<=1.8 版本和Picasso<=2.4版本。

7.5 重寫響應

相對應地,攔截器可以重寫響應頭和改變響應體。這一點比重寫寫請求頭要危險,因為可能違反web伺服器的期望。

如果你處於一種比較糾結的狀態,並且準備處理結果,那麼重寫響應頭是解決問題的有效方法。例如,可以修復伺服器配置錯誤的Cache-Control響應頭是快取更高效。


典型情況,這樣做比在伺服器上處理這個問題要方便得多。

7.6 實用性

OkHttp攔截器在OkHttp2.2以後更優。不過,沒有OkUrlFactory,攔截器無法工作,基於OkHttp構建的框架有Retrofit<=1.8 版本和Picasso<=2.4版本。