美文网首页网络专题网络请求OKHTTP学习
OKHTTP结合官网示例分析两种自定义拦截器的区别

OKHTTP结合官网示例分析两种自定义拦截器的区别

作者: 未见哥哥 | 来源:发表于2017-07-11 20:24 被阅读2927次

    OKHTTP异步和同步请求简单分析
    OKHTTP拦截器缓存策略CacheInterceptor的简单分析
    OKHTTP拦截器ConnectInterceptor的简单分析
    OKHTTP拦截器CallServerInterceptor的简单分析
    OKHTTP拦截器BridgeInterceptor的简单分析
    OKHTTP拦截器RetryAndFollowUpInterceptor的简单分析
    OKHTTP结合官网示例分析两种自定义拦截器的区别

    1、LoggingInterceptor示例代码

    通过下面的代码可以看出,它就是用于在请求发送前和网络响应后的打印日志信息的拦截器。具体打印的内容很简单,就不解释了,重点是 Application Intercetor 和 NetworkInterceptor 的区别,继续往下看。

    class LoggingInterceptor implements Interceptor {
      @Override public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();
        
        //请求前--打印请求信息
        long t1 = System.nanoTime();
        logger.info(String.format("Sending request %s on %s%n%s",
            request.url(), chain.connection(), request.headers()));
    
        //网络请求
        Response response = chain.proceed(request);
    
        //网络响应后--打印响应信息
        long t2 = System.nanoTime();
        logger.info(String.format("Received response for %s in %.1fms%n%s",
            response.request().url(), (t2 - t1) / 1e6d, response.headers()));
    
        return response;
      }
    }
    

    2、Application Intercetor和NetworkInterceptor的区别

    在官方文档中用 LoggingInterceptor 作为示例,解释了 Application Intercetor 和 NetworkInterceptor 的区别。

    OKHTTP官网示例在看两种拦截器的区别之前,还是要点击这个链接去看看,之后再看这个博客的总结会好点。

    到这里,默认就是已经看过了官网的示例了,那我们就使用一个图来看看拦截器的调用过程:

    拦截器的执行过程.png

    从上面的调用关系可以看出除了红色圈出的拦截器之外都是系统提供的拦截器,这整个过程是递归的执行过程,在 CallServerInterceptor 中得到最终的 Response 之后,将 response 按递归逐级进行返回,期间会经过 NetworkInterceptor 最后到达自定义的 Interceptor 。

    在官网给出的 NetworkInterceptor 和 Application Interceptor 的区别在上面的图中就可以看出:

    • 1.自定义 Interceptor 是第一个 Interceptor 因此它会被第一个执行,因此这里的 request 还是最原始的,并没有经过 BridgeInterceptor 进行加工过,因此他只有一个自定义的 User-Agent 请求头。而对于 response 而言呢,因为整个过程是递归的调用过程,因此它会在 CallServerInterceptor 执行完毕之后才会将 Response 进行返回,因此这里得到的 response 就是最终的响应,虽然中间有重定向,但是这里只关心最终的 response 。

    • 2.NetwrokInterceptor 处于第 6 个拦截器中,它会经过 RetryAndFollowIntercptor 进行重定向并且也会通过 BridgeInterceptor 进行 request 请求头和 响应 resposne 的处理,因此这里可以得到的是更多的信息。在打印结果可以看到它内部是发生了一次重定向操作,在上图可以看出,为什么 NetworkInterceptor 可以比 Application Interceptor 得到更多的信息了。

    3、两种拦截器的区别

    下面是官网给出的区别,根据我自己的理解,使用中文标出了自己的解释。

    Application interceptors

    • 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.只关注最原始的请求,不去关系请求的资源是否发生了改变,我只关注最后的 response 结果而已。
    • Permitted to short-circuit and not call Chain.proceed().因为是第一个被执行的拦截器,因此它有权决定了是否要调用其他拦截,也就是 Chain.proceed() 方法是否要被执行。
    • Permitted to retry and make multiple calls to Chain.proceed()
      .因为是第一个被执行的拦截器,因此它有可以多次调用 Chain.proceed() 方法,其实也就是相当与重新请求的作用了。

    Network Interceptors

    • Able to operate on intermediate responses like redirects and retries.因为 NetworkInterceptor 是排在第 6 个拦截器中,因此会经过 RetryAndFollowup 进行失败重试或者重定向,因此可以操作中间的 resposne。
    • Not invoked for cached responses that short-circuit the network.这个我不知道是什么意思,望大神指点。TODO
    • Observe the data just as it will be transmitted over the network.观察数据在网络中的传输,具体我也不太清除是干嘛的。TODO
    • Access to the Connection that carries the request.因为它排在 ConnectInterceptor 后执行,因此返回执行这个 request 请求的 Connection 连接。

    在上面还有几个 TODO 没有解决,希望懂的同学指点一下...

    相关文章

      网友评论

      • 醉卧赏血:Observe the data just as it will be transmitted over the network.其实就是观察网络通讯中数据的变化,比如重定向时我们就可以通过网络拦截器打印log来确定某个接口确实存在重定向的情况,其他特殊请求情况也是这样
      • 醉卧赏血:Not invoked for cached responses that short-circuit the network.根据之前的源码阅读,这句话表示如果客户端在使用缓存的情况下(当前仅支持get方式缓存),那么就不会调用网络拦截器。
      • 橘子周二:哈喽,我最近也在研究okhttp缓存以及如何动态切换缓存策略,首先上面的TODO的地方我还没有去阅读,希望看到你持续更新
        未见哥哥:@_RANGO OK

      本文标题:OKHTTP结合官网示例分析两种自定义拦截器的区别

      本文链接:https://www.haomeiwen.com/subject/ignmhxtx.html