OkHttp原理解析之重试及重定向拦截器

本文介绍OkHttp中的RetryAndFollowUpInterceptor拦截器如何处理重试与重定向逻辑。针对RouteException和IOException异常,通过recover方法判断是否重试;对于特定响应码,如301、302等,通过followUpRequest方法实现重定向。

一、重试及重定向拦截器

第一个拦截器:RetryAndFollowUpInterceptor,主要就是完成两件事情:重试与重定向。

重试

在这里插入图片描述
请求阶段发生了 RouteException 或者 IOException会进行判断是否重新发起请求。

RouteException:

catch (RouteException e) {
   
   
	//todo 路由异常,连接未成功,请求还没发出去
    if (!recover(e.getLastConnectException(), streamAllocation, false, request)) {
   
   
    	throw e.getLastConnectException();
    }
    releaseConnection = false;
    continue;
} 

IOException:

catch (IOException e) {
   
   
	//todo 请求发出去了,但是和服务器通信失败了。(socket流正在读写数据的时候断开连接)
    // ConnectionShutdownException只对HTTP2存在。假定它就是false
	boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
	if (!recover(e, streamAllocation, requestSendStarted, request)) throw e;
		releaseConnection = false;
		continue;
} 

两个异常都是根据recover 方法判断是否能够进行重试,如果返回true,则表示允许重试。

private boolean recover(IOException e, StreamAllocation streamAllocation,
                            boolean requestSendStarted, Request userRequest) {
   
   
	streamAllocation.streamFailed(e);
	//todo 1、在配置OkhttpClient是设置了不允许重试(默认允许),则一旦发生请求失败就不再重试
	if (!client.retryOnConnectionFailure()) return false;
	//todo 2、由于requestSendStarted只在http2的io异常中为true,http1中一定是false,先不管http2
	if (requestSendStarted && userRequest.body() instanceof UnrepeatableRequestBody)
		return false;

	//todo 3、判断是不是属于可重试的异常
	if (!isRecoverable(e, requestSendStarted)) return false;

	//todo 4、判断是否存在更多的路由,如果域名可以解析出多个ip或者配置了多个http代理,那么hasMoreRoutes就为true
	if (!streamAllocation.hasMoreRoutes()) return false;

	// For failure recovery, use the same route sele
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值