Apache HttpClient 4.5.x 學習總結六:Exception handling(異常處理)
以下是對HTTP異常處理內容的翻譯、知識點提煉及通俗解釋:
通俗解釋:
場景類比:網購訂單系統
-
異常類型
- 網絡抖動(IOException) → 快遞員聯系不上你(可重試)
- 協議錯誤(HttpException) → 填錯收貨地址(需人工修正)
-
冪等性重要性
- 你點擊"付款"但網絡卡頓 → 重復提交 → 冪等設計:
? 生成唯一訂單號 → 即使重復提交也只扣款1次
? 無冪等設計 → 可能扣款多次
- 你點擊"付款"但網絡卡頓 → 重復提交 → 冪等設計:
-
自動重試規則
- 快遞員發現:
? 未發貨時運輸車故障 → 換車重發(類似GET請求重試)
? 已發貨后包裹丟失 → 不再自動重發(類似POST請求)
- 快遞員發現:
-
自定義重試策略
自定義規則 = { 最多重試5次, 不重試:超時/SSL錯誤/主機失聯, 僅重試:查詢類請求(不下單的請求) }就像電商平臺設置:"對查詢庫存請求自動重試3次,但支付請求必須人工確認"
翻譯:
1.5 異常處理
HTTP處理器拋出兩類異常:
- IOException:I/O故障(如超時/連接斷開),通常可恢復
- HttpException:HTTP協議錯誤(如協議違規),通常致命
注:HttpClient將HttpException轉為ClientProtocolException(IOException子類),方便統一捕獲
1.5.1 HTTP傳輸安全性
HTTP不適于事務型操作:服務器執行請求后即使客戶端未完整接收響應(如超時/崩潰),也不會回滾事務。重試請求可能導致:
- 重復執行事務
- 數據損壞
- 狀態不一致
1.5.2 冪等方法
冪等性定義:"N>0次相同請求產生的副作用 = 單次請求"
解決方案:
- 使用唯一事務ID
- 避免重復執行邏輯操作
默認冪等方法判定:
? GET/HEAD(無請求體)
? POST/PUT(含請求體)
1.5.3 自動恢復機制
- 僅自動恢復I/O異常(非協議異常)
- 自動重試場景:
- 冪等方法(如GET)
- 請求未完全發出時失敗
1.5.4 自定義重試處理器
HttpRequestRetryHandler myRetryHandler = (exception, retryCount, context) -> {
if (retryCount >= 5) return false; // 最多重試5次
if (exception 是超時/SSL等錯誤) return false; // 不重試特定錯誤
HttpRequest request = HttpClientContext.adapt(context).getRequest();
// 僅重試冪等方法(非含實體的請求)
return !(request instanceof HttpEntityEnclosingRequest);
};
// 應用自定義重試器
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(myRetryHandler)
.build();
提示:可用StandardHttpRequestRetryHandler默認支持RFC定義的冪等方法(GET/HEAD/PUT/DELETE/OPTIONS/TRACE)
核心知識點提煉:
| 主題 | 關鍵點 |
|---|---|
| 異常類型 | IOException(可恢復) vs HttpException(致命)→轉為ClientProtocolException |
| HTTP事務缺陷 | 請求執行后不回滾 → 重試導致重復執行 → 需冪等性保障 |
| 冪等性 | 多次執行效果 = 單次執行(GET/HEAD/PUT/DELETE等) |
| 自動恢復 | 僅重試:1) 冪等方法 2) 請求未完全發出時的I/O錯誤 |
| 重試處理器 | 通過HttpRequestRetryHandler自定義重試邏輯 |
關鍵結論:HTTP協議不是為金融級交易設計的,必須通過冪等性設計+智能重試策略規避數據重復風險。
浙公網安備 33010602011771號