servlet 攔截器,攔截器RetryAndFollowUpInterceptor分析

 2023-10-20 阅读 30 评论 0

摘要:RetryAndFollowUpInterceptor攔截器 前面已經分析,okHttp的線程池里的請求任務的execute方法會構造攔截器鏈,然后通過index++依次調用chain.proceed方法來調用各種攔截器,不考慮用戶自定義的攔截器的話,第一個被調用的攔截器就是RetryAnd

RetryAndFollowUpInterceptor攔截器

前面已經分析,okHttp的線程池里的請求任務的execute方法會構造攔截器鏈,然后通過index++依次調用chain.proceed方法來調用各種攔截器,不考慮用戶自定義的攔截器的話,第一個被調用的攔截器就是RetryAndFollowUpInterceptor,請求重試攔截器,我們主要看被調用的方法intercept

public Response intercept(Chain chain) throws IOException {Request request = chain.request();RealInterceptorChain realChain = (RealInterceptorChain) chain;Call call = realChain.call();EventListener eventListener = realChain.eventListener();//StreamAllocation用于協調 連接Connections、數據流Streams 和 網絡請求Calls這三個實體StreamAllocation streamAllocation = new StreamAllocation(client.connectionPool(),createAddress(request.url()), call, eventListener, callStackTrace);this.streamAllocation = streamAllocation;//重定向次數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) {//捕獲RouteException,并判斷本次請求的異常是否能通過重新請求來恢復(比方ProtocolException協議出錯,則返回false不能重連)if (!recover(e.getLastConnectException(), streamAllocation, false, request)) {//不能則拋異常throw e.getFirstConnectException();}releaseConnection = false;//可以則continue,while循環體內重新請求一遍continue;} catch (IOException e) {//邏輯和上面的一樣,捕獲更大范圍的異常boolean requestSendStarted = !(e instanceof ConnectionShutdownException);if (!recover(e, streamAllocation, requestSendStarted, request)) throw e;releaseConnection = false;continue;} finally {//釋放當前的連接資源if (releaseConnection) {streamAllocation.streamFailed(null);streamAllocation.release();}}// Attach the prior response if it exists. Such responses never have a body.if (priorResponse != null) {response = response.newBuilder().priorResponse(priorResponse.newBuilder().body(null).build()).build();}Request followUp;try {//如果上面返回了response,那么判斷httpCode,具體的code做具體處理(比方407,代理認證失敗,則調用代理管理類進行認證)followUp = followUpRequest(response, streamAllocation.route());} catch (IOException e) {streamAllocation.release();throw e;}//沒有進一步的處理方法,(包括請求成功的)則返回null,此時直接返回response給上層處理if (followUp == null) {streamAllocation.release();return response;}closeQuietly(response.body());//重定向次數如果大于最大允許的重定向次數,則拋異常if (++followUpCount > MAX_FOLLOW_UPS) {streamAllocation.release();throw new ProtocolException("Too many follow-up requests: " + followUpCount);}if (followUp.body() instanceof UnrepeatableRequestBody) {streamAllocation.release();throw new HttpRetryException("Cannot retry streamed HTTP body", response.code());}if (!sameConnection(response, followUp.url())) {streamAllocation.release();streamAllocation = new StreamAllocation(client.connectionPool(),createAddress(followUp.url()), call, eventListener, callStackTrace);this.streamAllocation = streamAllocation;} 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;}
}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/152133.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息