天天看点

《HttpClient官方文档》1.5 异常处理

http协议处理器会抛出两种类型的异常: 一种是i/o失败的情况下产生的java.io.ioexception,比如套接字超时或重置。 另一种是发送http信号失败情况下的httpexception,比如违反http协议。 通常情况,我们认为i/o错误是非致命且可恢复的错误,而http协议错误则是致命且不能自动恢复的。 请注意,httpclient将httpexception重新封装成一个ioexception的子类clientprotocolexception,这样用户就可以在一个catch代码块中同时处理i/o错误和违反协议的错误。

很重要的一点是,http协议并不适用于所有类型的应用程序。 http是一个简单的面相request/response的协议,它的设计初衷是为了支持静态或动态地生成内容检索。 它从未打算支持事务操作,比如,当http服务器成功地接收并处理了客户端发送的请求,生成相应并发送回状态码,那么它会就认为完成了约定的内容。 如果由于读超时,请求取消或者系统崩溃等原因导致客户端无法成功接收到响应,那么服务器不会试图去回滚事务。如果客户端决定重试相同的请求,服务器最终将不可避免地多次执行相同的事务。 在某些情况下,这有可能导致应用程序的数据污染或状态不一致。 尽管http从未被设计成支持事务处理,但是它仍然可以作为一种在特定条件下满足特殊任务的传输协议。 为了保证http传输层的安全性,系统必须保证应用层中的http方法是幂等的。

http / 1.1规范定义了一个幂等方法[n > 0 的多次请求同单次请求产生的效果一样(除了错误或过期问题),这样的方法具有“幂等性”的性质]。换句话说,应用程序应该确保处理多次执行含义相同的方法的情况。 比如,应用程序可以通过提供一个独特的transaction id或者通过其他方式避免执行相同的逻辑操作来实现。 请注意,这个问题并不局限于httpclient。 基于浏览器的应用程序正是受同样涉及非幂等性的http方法影响。

默认情况下httpclient尝试从i/o exception中自动恢复。默认的自动恢复机制只局限于少数已知的安全的异常。

httpclient不会试图从任何逻辑或http协议错误(衍生自httpexception类)中恢复。

httpclient将自动重试那些被认为是等幂的方法。

httpclient将自动重试那些因传输异常而失败但是http请求仍然会被发送到目标服务器的方法。(即请求还没有完全被发送到服务器端)

为了使自定义异常恢复机制有效,实现了httprequestretryhandler接口。

请注意,为了处理安全自动的重试rfc-2616协议中定义的请求方法get,head,put,delete,options和trace,可以用standardhttprequestretryhandler代替使用默认的。

继续阅读