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号