《HttpClient官方文档》1.5 异常处理
1.5. 异常处理
HTTP协议处理器会抛出两种类型的异常: 一种是I/O失败的情况下产生的java.io.IOException,比如套接字超时或重置。 另一种是发送HTTP信号失败情况下的HttpException,比如违反HTTP协议。 通常情况,我们认为I/O错误是非致命且可恢复的错误,而HTTP协议错误则是致命且不能自动恢复的。 请注意,HttpClient将HttpException重新封装成一个IOException的子类ClientProtocolException,这样用户就可以在一个catch代码块中同时处理I/O错误和违反协议的错误。
1.5.1. HTTP 传输安全
很重要的一点是,HTTP协议并不适用于所有类型的应用程序。 HTTP是一个简单的面相request/response的协议,它的设计初衷是为了支持静态或动态地生成内容检索。 它从未打算支持事务操作,比如,当HTTP服务器成功地接收并处理了客户端发送的请求,生成相应并发送回状态码,那么它会就认为完成了约定的内容。 如果由于读超时,请求取消或者系统崩溃等原因导致客户端无法成功接收到响应,那么服务器不会试图去回滚事务。如果客户端决定重试相同的请求,服务器最终将不可避免地多次执行相同的事务。 在某些情况下,这有可能导致应用程序的数据污染或状态不一致。 尽管HTTP从未被设计成支持事务处理,但是它仍然可以作为一种在特定条件下满足特殊任务的传输协议。 为了保证HTTP传输层的安全性,系统必须保证应用层中的HTTP方法是幂等的。
1.5.2. 幂等方法
HTTP / 1.1规范定义了一个幂等方法[N > 0 的多次请求同单次请求产生的效果一样(除了错误或过期问题),这样的方法具有“幂等性”的性质]。换句话说,应用程序应该确保处理多次执行含义相同的方法的情况。 比如,应用程序可以通过提供一个独特的transaction id或者通过其他方式避免执行相同的逻辑操作来实现。 请注意,这个问题并不局限于HttpClient。 基于浏览器的应用程序正是受同样涉及非幂等性的HTTP方法影响。
1.5.3. 异常自动恢复
默认情况下HttpClient尝试从I/O exception中自动恢复。默认的自动恢复机制只局限于少数已知的安全的异常。
- HttpClient不会试图从任何逻辑或HTTP协议错误(衍生自HttpException类)中恢复。
- HttpClient将自动重试那些被认为是等幂的方法。
- HttpClient将自动重试那些因传输异常而失败但是HTTP请求仍然会被发送到目标服务器的方法。(即请求还没有完全被发送到服务器端)
1.5.4. 请求重试处理
为了使自定义异常恢复机制有效,实现了HttpRequestRetryHandler接口。
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(
IOException exception,
int executionCount,
HttpContext context) {
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(myRetryHandler)
.build();
请注意,为了处理安全自动的重试RFC-2616协议中定义的请求方法GET,HEAD,PUT,DELETE,OPTIONS和TRACE,可以用StandardHttpRequestRetryHandler代替使用默认的。
原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《HttpClient官方文档》1.5 异常处理
暂无评论