您的位置:首页 > 理论基础 > 计算机网络

OkHttp框架的RetryAndFollowUpInterceptor请求重定向源码解析

2017-06-25 21:26 471 查看
在OkHttp框架中,当客户端通过OkHttpClient发起同步或异步请求时,OkHttp框架将会创建一个RealCall,这个实例将根据客户端提供的Request,发起同步或异步网络请求操作,在RealCall被创建时,将会创建一个Interceptor的具体实现。我们知道,OkHttp框架将网络请求的步骤,通过Interceptor接口进行了统一的分层式设计,将每个环节都分成了不同的Interceptor,Interceptor又被称为拦截器,这是该网络框架设计的精髓所在,通过不同的拦截器规则,处理网络请求过程中的不同环节,最终通过链式调用,实现一个完整的网络请求操作。
通过查看一下这个流程图可以看出,网络请求的每一个不同环节,都是通过不同的Interceptor实现的,在执行链式调用后,最终组织完整的Response。




接下来我们分析RealCall在创建时所执行的操作,进入RealCall的构造方法可以看出,这里创建了一个拦截器RetryAndFollowUpInterceptor实例,这个拦截器它的作用主要是负责请求的重定向操作,用于处理网络请求中,请求失败后的重试机制。因此,稍后会详细分析RetryAndFollowUpInterceptor重定向机制,关于RealCall的构造方法,源代码如下所示。



一、RetryAndFollowUpInterceptor请求重定向源码分析

当请求重定向被执行时,会执行intercept这个方法,关于请求重定向处理,就从这里开始进行分析。

首先,会根据客户端请求Request以及OkHttpClient,创建出StreamAllocation,它主要用于管理客户端与服务器之间的连接,同时管理连接池,以及请求成功后的连接释放等操作,源代码如下所示。



在执行StreamAllocation创建时,可以看到根据客户端请求的地址url,还调用了createAddress方法。进入该方法可以看出,这里返回了一个创建成功的Address,实际上Address就是将客户端请求的网络地址,以及服务器的相关信息,进行了统一的包装,也就是将客户端请求的数据,转换为OkHttp框架中所定义的服务器规范,这样一来,OkHttp框架就可以根据这个规范来与服务器之间进行请求分发了。关于createAddress方法的源代码如下所示,我们这里不针对Address进行详细分析。



这时我们分析StreamAllocation的构造方法,观察此构造方法可以看出,StreamAllocation创建时,又根据Address,创建了一个路由选择器RouteSelector,可以这样理解,OkHttp通过层层的封装,将请求的服务器相关信息,封装到了不同层次中,而每个层次所处理的职责不同,而Address、RouteSelector等,都是不同层次中,用于对服务器相关信息的包装处理,同时也起到了桥梁的作用。关于StreamAllocation的源代码,如下所示。



接下来继续回到RetryAndFollowUpInterceptor,这时会进入一个while循环,在这个循环中,首先会进行一个安全检查操作,检查当前请求是否被取消,如果这时请求被取消了,则会通过StreamAllocation释放连接,并抛出异常,源代码如下所示。



如果这时没有发生上述情况,接下来会通过RealInterceptorChain的proceed方法处理请求,在请求过程中,只要发生异常,releaseConnection就会为true,一旦变为true,就会将StreamAllocation释放掉,源代码如下所示。



如果这时没有产生异常情况,接下来则会通过响应Response来执行followUpRequest方法,来检查是否需要进行重定向操作。这里我们暂且先不分析此方法,继续在while循环中向下分析,当不需要进行重新定向操作时,就会直接返回Response,源代码如下所示。



由于这些操作都是在while循环中执行的,由于此时不需要进行请求重定向处理,并直接返回了Response。所以,接下来RealInterceptorChain就会在循环中继续分发并执行下一个拦截器,我们通过观察流程图可以看出,下一个拦截器是BridgeInterceptor。

这些都是目前正常情况下,RetryAndFollowUpInterceptor重定向机制的处理流程,接下来我们分析当请求发生异常时,RetryAndFollowUpInterceptor是如何处理重定向操作的。

如果这时需要进行请求重定向操作,那么此时followUp这个请求头就不会为空,接下来首先对重定向请求进行了两个安全检查,代码如下所示。



然后根据重定向请求followUp,与当前的响应进行对比,检查是否同一个连接。通常,当发生请求重定向时,url地址将会有所不同,也就是说,请求的资源在这时已经被分配了新的url。因此,接下来的!sameConnection这个判断将会符合,该这个方法就是用来检查重定向请求,和当前的请求,是否为同一个连接。一般来说,客户端进行重定向请求时,需要与新的url建立连接,而原先的连接,则需要进行销毁。



通过观察上面这段代码可以看出,当发现重定向请求的followUp与当前请求的不是同一个连接时,首先通过StreamAllocation执行了release方法,将当前连接销毁掉。然后,根据重定向请求获取到的新的url,再次创建了一个新的StreamAllocation连接。

在最后,还会看到这样一行代码,就是将重定向得到的新请求followUp,赋值给了request,这样,在while循环中,就可以根据根据重定向操作,重新生成的这个新的Request,继续向客户端发送请求获取数据了,代码如下所示。



在OkHttp的RetryAndFollowUpInterceptor请求重定向的Interceptor中,是如何决定是否需要重定向的,这其实是根据当前请求获取的Response,来决定是否需要进行重定向操作。而处理是否重定向操作,是由followUpRequest方法来完成的,接下来我们详细分析该方法是如何根据当前的Response,来重新生成重定向请求Request的。

我们知道,是否需要进行请求重定向,是根据http请求的响应码来决定的,因此,在followUpRequest方法中,将会根据响应userResponse,获取到响应码,并从连接池StreamAllocation中获取连接,然后根据当前连接,得到路由配置参数Route。观察以下代码可以看出,这里通过userResponse得到了响应码responseCode。



接下来将会根据响应码responseCode来检查当前是否需要进行请求重定向,我们知道,在Http响应码中,处于3XX的,都需要进行请求重定向处理。因此,接下来该方法会通过switch…case…来进行不同的响应码处理操作。

从这段代码开始,都是3xx的响应码处理,这里就开始进行请求重定向的处理操作。



执行重定向请求构建前,首先根据OkHttpClient,执行了followRedirects方法,检查客户端是否允许进行重定向请求。如果这时客户端未允许重定向,则会返回null。

接下来根据响应获取到位置location,然后根据location,得到重定向的url,代码如下所示。



接下来这一大段代码就是重新构建Request的过程,根据重定向得到的url,重新构建Request请求,并对请求中的header和body分别进行处理,最后可以看到,通过build模式,将新构建的Request请求进行返回。



当返回重定向新生成的Request请求后,接下来的步骤,就是我们前面分析的过程了。这里关于OkHttp框架中的重定向RetryAndFollowUpInterceptor处理流程,就已经分析完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: