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框架同时使用。

猜你喜欢

转载自blog.csdn.net/qq_42120002/article/details/80548651