OkHttp3初探:拦截器源码分析

本文详细介绍了OkHttp3的拦截器机制,包括Interceptor接口、RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor、CallServerInterceptor,以及addInterceptor和addNetworkInterceptor的区别。在OkHttp3网络请求过程中,拦截器按顺序执行,处理重定向、缓存、网络连接等问题,为网络请求提供了灵活的控制和优化。
摘要由CSDN通过智能技术生成

目录

一、OkHttp3的拦截器

二、Interceptor接口

三、RetryAndFollowUpInterceptor

三、BridgeInterceptor

四、CacheInterceptor

五、ConnectInterceptor

六、CallServerInterceptor

七、addInterceptor与addNetworkInterceptor的区别

八、主要参考


 


一、OkHttp3的拦截器

在OkHttp3中,在执行RealCall的execute方法时,在通过HttpClient的Dispatcher执行execute方法后,将当前RealCall添加到执行/等待队列中,然后调用getResponseWithInterceptorChain()方法返回的Response;

在getResponseWithInterceptorChain()方法中,在真正执行网络请求前,会先添加上一串拦截器Interceptor,如下所示:

/** getResponseWithInterceptorChain@RealCall.class */
/** 执行网络请求,并返回服务器响应Response */
Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    // 拦截器容器
    List<Interceptor> interceptors = new ArrayList<>();
    // 1.先添加用户自定义的拦截器
    interceptors.addAll(client.interceptors());
  	// 2.重试与重定向拦截器,如重连接,对3xx系列重连接做出响应
    interceptors.add(new RetryAndFollowUpInterceptor(client));
  	// 3.桥接拦截器,切换对用户友好的Request/Response与对服务器友好的Request/Response;
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
  	// 4.缓存拦截器,用来处理网络缓存;
    interceptors.add(new CacheInterceptor(client.internalCache()));
    // 5.IO连接拦截器,真实IO操作;
    interceptors.add(new ConnectInterceptor(client));
  
    
    if (!forWebSocket) {
      // 6.如果不是WebSocket长链接,添加用户自定义的网络拦截器
      interceptors.addAll(client.networkInterceptors());
    }
  	// 7.服务器连接拦截器,连接服务器;
    interceptors.add(new CallServerInterceptor(forWebSocket));

    // 创建拦截器链的实例
    Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null,0,
        originalRequest, this, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    boolean calledNoMoreExchanges = false;
    try {
      // 开始递归调用不同拦截器,并得到服务器返回结果
      Response response = chain.proceed(originalRequest);
      if (transmitter.isCanceled()) {
        closeQuietly(response);
        throw new IOException("Canceled");
      }
      return response;
    } catch (IOException e) {
      calledNoMoreExchanges = true;
      throw transmitter.noMoreExchanges(e);
    } finally {
      if (!calledNoMoreExchanges) {
        transmitter.noMoreExchanges(null);
      }
    }
  }

二、Interceptor接口

/**  Interceptor.class interface*/
/**
 * 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 {
  
  /** 入参为拦截器链,返回值为Http响应Response */
  Response intercept(Chain chain) throws IOException;

  /** 内部接口 */
  interface Chain {
    Request request();
		
    /** 发起网络请求方法 */
    Response proceed(Request request) throws IOException;

    /**
     * Returns the connection the request will be executed on.
     * This is only available in the chains of network interceptors; 
     * for application interceptors this is always null.
     */
    @Nullable Connection connection();

    Call call();

    int connectTimeoutMillis();

    Chain withConnectTimeout(int timeout, TimeUnit unit);

    int readTimeoutMillis();

    Chain withReadTimeout(int timeout, TimeUnit unit);

    int writeTimeoutMillis();

    Chain withWriteTimeout(int timeout, TimeUnit unit);
  }
}

每个Interceptor都要实现Interceptor接口;其中intercept()方法作为拦截器的拦截方法,执行具体逻辑,proceed()方法作为递归调用下一个拦截器的方法,从而保证拦截器链按顺序执行下去;

三、RetryAndFollowUpInterceptor

重连接与重定向拦截器:在intercept()方法中先做好网络连接前的准备,如果网络请求没有被取消掉,就开始递归调用proceed方法,获取下一层Interceptor的返回值,赋值给Response对象,在递归的过程中可能会出现异常,比如服务器返回3XX类型的重定向Reponse,则根据Response携带的信息,在followUpRequest方法中创建新的Request对象,这里命名为followUp。默认最多可重定向20次,超过20次则抛出异常;如果出现IO类连接关闭异常,则会重试;

/** intercept@RetryAndFollowUpInterceptor */
/** 拦截方法 */
@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    Transmitter transmitter = realChain.transmitter();
    int followUpCount = 0;
    Response priorResponse = null;
    while (true) {
        transmitter.prepareToConnect(request);
        if (transmitter.isCanceled()) {
            throw new IOException("Canceled");
        }
        Response response;
        boolean success = false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值