1. 程式人生 > >okhttp攔截器的使用

okhttp攔截器的使用

本篇介紹OkHttp的攔截器的使用。
首先我們需要了解什麼事攔截器。打個比方,鏢局押著一箱元寶在行走在一個山間小路上,突然從山上下來一群山賊攔住了鏢局的去路,將鏢局身上值錢的東西搜刮乾淨後將其放行。其中山賊相當於攔截器,鏢局相當於一個正在執行任務的網路請求,請求中的引數就是鏢局攜帶的元寶。攔截器可以將網路請求攜帶的引數進行修改驗證,然後放行。這裡面其實設計了AOP程式設計的思想(面向切面程式設計)。
  • 攔截器的作用和好處。
在介紹攔截器的作用和好處之前,我們還是要回到山賊這個角色上,如果讓你做一次山賊,你會在什麼地方埋伏?肯定是在鏢局必經之路上埋伏。也就是說,攔截器就是在所有的網路請求的必經之地上進行攔截。

1、攔截器可以一次性對所有的請求和返回值進行修改。
2、攔截器可以一次性對請求的引數和返回的結果進行編碼,比如統一設定為UTF-8.
3、攔截器可以對所有的請求做統一的日誌記錄,不需要在每個請求開始或者結束的位置都新增一個日誌操作。
4、其他需要對請求和返回進行統一處理的需求….
  • OkHttp中攔截器分類
OkHttp中的攔截器分2個:APP層面的攔截器(Application Interception)、網路請求層面的攔截器(Network Interception)。如下圖:
 
一、Application Interceptor是在請求執行剛開始,還沒有執行OkHttp的核心程式碼前進行攔截,Application攔截器的作用:

1、不需要擔心是否影響OKHttp的請求策略和請求速度。
2、即使是從快取中取資料,也會執行Application攔截器。
3、允許重試,即Chain.proceed()可以執行多次。(當然請不要盲目執行多次,需要加入你的邏輯判斷)
二、Network Interception是在連線網路之前(如圖,看圖一目瞭然)
1、可以修改OkHttp框架自動新增的一些屬性(當然最好不要修改)。
2、可以觀察最終完整的請求引數(也就是最終伺服器接收到的請求資料和熟悉)
  • 例項化一個攔截器
  1. Interceptor appInterceptor = new Interceptor() {
  2.         @Override
  3.         public Response intercept(Chain chain) throws IOException {
  4.             Request request = chain.request();
  5.             //———請求之前————
  6.             Response response = chain.proceed(request1);
  7.             //———請求之後————
  8.             return response;
  9.         }
  10.     };

複製程式碼

  • 配置攔截器
  1. okHttpClient = new OkHttpClient
  2.                 .Builder()
  3.                 .addInterceptor(appInterceptor)//Application攔截器
  4.                 .addNetworkInterceptor(networkInterceptor)//Network攔截器
  5.                 .build();

複製程式碼


其中通過addInterceptor新增應用攔截器,addNetworkInterceptor新增網路攔截器。
  • 示例程式碼
  1. public class InterceptorActivity extends AppCompatActivity {
  2.     public static final String TAG = “androidxx”;
  3.     OkHttpClient okHttpClient;
  4.     /**
  5.      * 應用攔截器
  6.      */
  7.     Interceptor appInterceptor = new Interceptor() {
  8.         @Override
  9.         public Response intercept(Chain chain) throws IOException {
  10.             Request request = chain.request();
  11.             HttpUrl url = request.url();
  12.             String s = url.url().toString();
  13.             //———請求之前—–
  14.             Log.d(TAG,”app interceptor:begin”);
  15.             Response  response = chain.proceed(request);
  16.             Log.d(TAG,”app interceptor:end”);
  17.             //———請求之後————
  18.             return response;
  19.         }
  20.     };
  21.     /**
  22.      * 網路攔截器
  23.      */
  24.     Interceptor networkInterceptor = new Interceptor() {
  25.         @Override
  26.         public Response intercept(Chain chain) throws IOException {
  27.             Request request = chain.request();
  28.             //———請求之前—–
  29.             Log.d(TAG,”network interceptor:begin”);
  30.             Response  response = chain.proceed(request);
  31.             Log.d(TAG,”network interceptor:end”);
  32.             return response;
  33.         }
  34.     };
  35.     @Override
  36.     protected void onCreate(Bundle savedInstanceState) {
  37.         super.onCreate(savedInstanceState);
  38.         setContentView(R.layout.activity_interceptor);
  39.         okHttpClient = new OkHttpClient
  40.                 .Builder()
  41.                 .addInterceptor(appInterceptor)//Application攔截器
  42.                 .addNetworkInterceptor(networkInterceptor)//Network攔截器
  43.                 .build();
  44.     }
  45.     public void click(View view) {
  46.         Request request = new Request.Builder().url(“http://www.androidxx.cn”).build();
  47.         okHttpClient.newCall(request).enqueue(new Callback() {
  48.             @Override
  49.             public void onFailure(Call call, IOException e) {
  50.                 e.printStackTrace();
  51.             }
  52.             @Override
  53.             public void onResponse(Call call, Response response) throws IOException {
  54.                 Log.d(TAG,”–” + response.networkResponse());
  55.             }
  56.         });
  57.     }
  58. }

複製程式碼


執行結果如下:

 



可以看到,從App Interceptor開始,然後執行Network Interceptor,最後又回到App Interceptor.


  • 建議

如果對攔截器不是很熟的同學,開發過程中,建議使用Application Interception。這樣避免對OkHttp請求策略的破壞。

  • 實際開發中的用途

1、對請求引數進行統一加密處理。

2、攔截不符合規則的URL。

3、對請求或者返回引數設定統一的編碼方式

4、其它…。

比如對URL進行驗證(如果Url中沒有包含androidxx關鍵字,則修改請求連結為http://www.androidxx.cn),程式碼如下:

  1. Interceptor appInterceptor = new Interceptor() {
  2.         @Override
  3.         public Response intercept(Chain chain) throws IOException {
  4.             Request request = chain.request();
  5.             HttpUrl url = request.url();
  6.             String s = url.url().toString();
  7. Response  response = null;
  8.             //如果Url中沒有包含androidxx關鍵字,則修改請求連結為http://www.androidxx.cn
  9.             if (s.contains(“androidxx”)) {
  10.                 request = request.newBuilder().url(“http://www.androidxx.cn”).build();
  11.             }
  12.             response = chain.proceed(request);
  13. return response;
  14.         }
  15.     };

複製程式碼

  • 注意

OkHttp的攔截器是在OkHttp2.2之後才可以使用,並且攔截器不能與Retrofit ≤ 1.8和Picasso ≤ 2.4框架同時使用。