宏观流程
@Override public Response intercept(Chain chain) throws IOException {
。。。
while (true) {
。。。
try {
response = realChain.proceed(request, streamAllocation, null, null);
}
。。。
if(满足条件){
return response;
}
。。。
//不满足条件,一顿操作,赋值再来!
request = followUp;
priorResponse = response;
}
}
源码解读
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Call call = realChain.call();
EventListener eventListener = realChain.eventListener();
//streamAllocation的创建位置
streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(request.url()),
call, eventListener, callStackTrace);
int followUpCount = 0;
Response priorResponse = null;
while (true) {
//取消
if (canceled) {
streamAllocation.release();
throw new IOException("Canceled");
}
Response response;
boolean releaseConnection = true;
try {
response = realChain.proceed(request, streamAllocation, null, null);
releaseConnection = false;
} catch (RouteException e) {
// The attempt to connect via a route failed. The request will not have been sent.
if (!recover(e.getLastConnectException(), false, request)) {
throw e.getLastConnectException();
}
releaseConnection = false;
//重试。。。
continue;
} catch (IOException e) {
// An attempt to communicate with a server failed. The request may have been sent.
//先判断当前请求是否已经发送了
boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
//同样的重试判断
if (!recover(e, requestSendStarted, request)) throw e;
releaseConnection = false;
//重试。。。
continue;
} finally {
// We're throwing an unchecked exception. Release any resources.
//没有捕获到的异常,最终要释放
if (releaseConnection) {
streamAllocation.streamFailed(null);
streamAllocation.release();
}
}
// Attach the prior response if it exists. Such responses never have a body.
//这里基本上都没有讲,priorResponse是用来保存前一个Resposne的,这里可以看到将前一个Response和当前的Resposne
//结合在一起了,对应的场景是,当获得Resposne后,发现需要重定向,则将当前Resposne设置给priorResponse,再执行一遍流程,
//直到不需要重定向了,则将priorResponse和Resposne结合起来。
if (priorResponse != null) {
response = response.newBuilder()
.priorResponse(priorResponse.newBuilder()
.body(null)
.build())
.build();
}
//判断是否需要重定向,如果需要重定向则返回一个重定向的Request,没有则为null
Request followUp = followUpRequest(response);
if (followUp == null) {
//不需要重定向
if (!forWebSocket) {
//是WebSocket,释放
streamAllocation.release();
}
//返回response
return response;
}
//需要重定向,关闭响应流
closeQuietly(response.body());
//重定向次数++,并且小于最大重定向次数MAX_FOLLOW_UPS(20)
if (++followUpCount > MAX_FOLLOW_UPS) {
streamAllocation.release();
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
//是UnrepeatableRequestBody, 刚才看过也就是是流类型,没有被缓存,不能重定向
if (followUp.body() instanceof UnrepeatableRequestBody) {
streamAllocation.release();
throw new HttpRetryException("Cannot retry streamed HTTP body", response.code());
}
//判断是否相同,不然重新创建一个streamConnection
if (!sameConnection(response, followUp.url())) {
streamAllocation.release();
streamAllocation = new StreamAllocation(client.connectionPool(),
createAddress(followUp.url()), call, eventListener, callStackTrace);
} else if (streamAllocation.codec() != null) {
throw new IllegalStateException("Closing the body of " + response
+ " didn't close its backing stream. Bad interceptor?");
}
//赋值再来!
request = followUp;
priorResponse = response;
}
}
总结:
-
初始化了连接的对象(StreamAllocation,但是比没有真正建立连接,只是初始化了对象)(前置拦截);
-
通过RealInterceptorChain,再调用下一个拦截器;
-
收到结果之后,做异常处理,判断是否重连或者重定向,或者返回结果。(后置拦截)