OkHttp中拦截器的简单介绍

OkHttp

官方文档

简介

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.
意思大概是,拦截器是一个强有力的机制,能够监控,重写以及重试(请求的)调用。

从上篇可以知道当call调用execute或者enqueue时,都是RealCall在调用,最终会执行Response result = getResponseWithInterceptorChain();这段代码.
execute

 @Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

getResponseWithInterceptorChain

  Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
  }

由此我们可以知道在getResponseWithInterceptorChain中添加了以下的拦截器:

  • client.interceptors():我们通过okHttpClient自定义的拦截器。
  • retryAndFollowUpInterceptor:重试及重定向拦截器
  • BridgeInterceptor:桥接拦截器
  • CacheInterceptor:缓存拦截器
  • ConnectInterceptor:连接拦截器
  • client.networkInterceptors():网络请求的拦截器
  • CallServerInterceptor(forWebSocket):读写拦截器

由此添加的顺序也可以得知拦截器执行的顺序。

拦截器的分类

在这里插入图片描述
从图中我们可以看出有两种拦截器,一种是Application Interceptors,另一种是Network Interceptors。中间这快OkHttp Core是内部拦截器。
不管是哪种拦截器,其都是基于Interceptor接口。我们来看看Interceptor这个接口!

/**
 * Observes, modifies, and potentially short-circuits requests going out and the corresponding
 * responses coming back in. Typically interceptors add, remove, or transform headers on the request
 * or response.
 */
public interface Interceptor {
  Response intercept(Chain chain) throws IOException;

  interface Chain {
    Request request();

    Response proceed(Request request) throws IOException;

    Connection connection();
  }
}

分为两类:

ApplicationInterceptor(应用拦截器)

  • Don’t need to worry about intermediate responses like redirects and retries.
    不需要关心是否重定向或者失败重连
  • Are always invoked once, even if the HTTP response is served from the cache.
    应用拦截器只会调用一次,即使数据来源于缓存
  • Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match.
    只考虑应用的初始意图,不去考虑Okhhtp注入的Header比如:if-None-Match,意思就是不管其他外在因素只考虑最终的返回结果
  • Permitted to short-circuit and not call Chain.proceed().
    自定义的应用拦截器是第一个开始执行的拦截器,所以这句话的意思就是,应用拦截器可以决定是否执行其他的拦截器,通过Chain.proceed().
  • Permitted to retry and make multiple calls to Chain.proceed().
    和上一句的意思差不多,可以执行多次调用其他拦截器,通过Chain.proceed().

NetworkInterceptor(网络拦截器)

  • Able to operate on intermediate responses like redirects and retries.
    网络拦截器可以操作重定向和失败重连的返回值
  • Not invoked for cached responses that short-circuit the network.
    取缓存中的数据就不会去执行Chain.proceed().所以就不能执行网络拦截器
  • Observe the data just as it will be transmitted over the network.
    通过网络拦截器可以观察到所有通过网络传输的数据
  • Access to the Connection that carries the request.
    请求服务连接的拦截器先于网络拦截器执行,所以在进行网络拦截器执行时,就可以看到Request中服务器请求连接信息,因为应用拦截器是获取不到对应的连接信息的。

异同

相同点:

  1. 都能对response和request进行拦截。
  2. 这两种拦截器本质上都是基于Interceptor接口,由开发者实现这个接口,然后将自定义的Interceptor类的对象设置到okhttpClient对象中。
  3. 两者都会被add到OkHttpClient内的一个ArrayList中。当请求执行的时候,多个拦截器会依次执行。

不同点:

  1. 添加应用拦截器的接口是addInterceptor(),而添加网络拦截器的接口是addNetworkInterceptor()。
  2. 作用区域不同,从最上方图中可以看出,应用拦截器作用于OkHttpCore到Application之间,网络拦截器作用于 Network和OkHttpCore之间。

案例

自定义应用拦截器
自定义CookieInterceptor来添加Request的Header信息,并且打印Response的头部信息
可以用来添加cookie信息,保存会话信息

public class CookieInterceptor implements Interceptor {

    private static String TAG = "CookieInterceptor";

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request().newBuilder()
                .addHeader("username","PurcellHuang")
                .addHeader("Cookie","sessionID=asdasfdsdas;token=asd15sadc4zxc15s")
                .build();

        Response response = chain.proceed(request);

        Headers headers = response.headers();
        Set<String> names = headers.names();
        for (String s:names){
            Log.i(TAG,"---------"+s+":"+headers.get(s));
        }


        return response;
    }
}

添加自定义拦截器

        //设置一下okHttp的参数
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS)
                .addInterceptor(new CookieInterceptor())
                .build();
        mRetrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)//设置BaseUrl
                .client(okHttpClient)//设置请求的client
                .addConverterFactory(GsonConverterFactory.create())//设置转换器
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值