HttpClient异常处理手册

异常处理 

HttpClient的使用者在执行HTPP方法(GET,PUT,DELETE等),可能遇到会两种主要类型的异常:

  • 传输异常
  • 协议异常

并不是所有的异常都会传播给HttpClient的用户。HttpClient内部使用的异常在下文中将会标记为内部使用

  • 传输异常
  • 协议异常
  • HTTP传输安全
  • 自动异常恢复
  • 自定义异常处理

传输异常 

传输异常都是诸如不可靠的连接到输入/输出失败或者未能在给与的时间内执行完HTPP方法(套接字超时)。一般来说,传输异常是非致命的错误,通过多次执行方法能够恢复。在非幕等方法中恢复特别需要注意(详细信息请参考HTTP传输安全)。 

 

java.io.IOException 

HttpCinet一般的传输异常可以用标准JAVA中 java.io.IOException或者其子类java.net.SocketException,java.net.InterruptedIOException来表示。 

为了规划化输入/输出异常类,HttpClient定义多种自定义传输异常用来传递HttpClient特定的信息。 

org.apache.commons.httpclient.NoHttpResponseException
java.io.IOException 
+- org.apache.commons.httpclient.NoHttpResponseException  

 

在某些情况下,由于服务器负载过大,服务器能接受到请求,但是没有能力去处理,像工作线程这样限制性资源就是一个很少的例子。这可能会导致服务器丢弃与客户端的连接,而不会给予任何回应。HttpClient遭遇这种情况时,抛出NoHttpResponseException 。在多数情况下,通过重试能够从此异常中恢复。 

org.apache.commons.httpclient.ConnectTimeoutException
java.io.IOException 
+- java.io.InterruptedIOException  

这种异常表示在给定的时间HttpClient与目标服务器或代理服务器建立起连接。 

 

org.apache.commons.httpclient.ConnectionPoolTimeoutException 

  1. java.io.IOException  
  2.   +- java.io.InterruptedIOException  
  3.     +- org.apache.commons.httpclient.ConnectTimeoutException  
  4.       +- org.apache.commons.httpclient.ConnectionPoolTimeoutException  

只有在使用多线程连接管理器时,才可能发生此异常。此异常表示在给定的时间从连接池中获取一个空闲连接失败。 

 

org.apache.commons.httpclient.HttpRecoverableException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.HttpRecoverableException  

废弃,任何标准HttpClient类中不会抛出此异常。 

 

协议异常 

HTTP规范的解释中,协议异常通常是由客户端与服务器(web服务器或是代理服务器)的不匹配导致的逻辑错误。如果不对客户端的请求或服务器做出调整,HttpClient此异常不能恢复。HTTP规范的多个方面允许不同甚至是相互冲突的解释。HttpClient能偶采用配置来支持从非常宽松到非常严格的HTTP规范的遵从度。 

 

org.apache.commons.httpclient.HttpException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  

HttpExceptionHttpClient中代表一个抽象逻辑错误,一般情况下,程序不能从这种错误中恢复。 

 

org.apache.commons.httpclient.ProtocolException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  

ProtocolException表示一个HTTP规范的冲突,值得注意的是HTTP代理服务器和HTTP服务器有着不同的HTTP规范的支持度级别。通过配置HttpClient更宽松可以让程序从非致命的协议冲突的HTTP协议异常恢复。 

 

org.apache.commons.httpclient.auth.MalformedChallengeException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  
  4.       +- org.apache.commons.httpclient.auth.MalformedChallengeException  

内部使用 

MalformedChallengeException表示一个身份认证凭证的某些方面在给定的身份认证的上下文中是无效或者非法的。 

 

org.apache.commons.httpclient.auth.AuthenticationException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  
  4.       +- org.apache.commons.httpclient.auth.AuthenticationException  

内部使用 

AuthenticationException用来表示身份认证过程中的失败。通常,认证异常不会传递给调用者,只在内部处理使用。 

 

org.apache.commons.httpclient.auth.AuthChallengeException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  
  4.       +- org.apache.commons.httpclient.auth.AuthenticationException  
  5.         +- org.apache.commons.httpclient.auth.AuthChallengeException  

内部使用 

HttpClient无法响应服务器发送的任何身份验证质询时,AuthenticationException将会抛出。 

 

org.apache.commons.httpclient.auth.CredentialsNotAvailableException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  
  4.       +- org.apache.commons.httpclient.auth.AuthenticationException  
  5.         +- org.apache.commons.httpclient.auth.CredentialsNotAvailableException

内部使用 

CredentialsNotAvailableException表明响应身份验证质询的要求的证书不可用。 

 

org.apache.commons.httpclient.auth.InvalidCredentialsException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  
  4.       +- org.apache.commons.httpclient.auth.AuthenticationException  
  5.         +- org.apache.commons.httpclient.auth.InvalidCredentialsException  

内部使用 

InvalidCredentialsException 表明响应身份验证质询的要求的证书被服务器拒绝。 

 

org.apache.commons.httpclient.cookie.MalformedCookieException 

java.io.IOException 

  +- org.apache.commons.httpclient.HttpException 

    +- org.apache.commons.httpclient.ProtocolException 

      +- org.apache.commons.httpclient.cookie.MalformedCookieException 

内部使用 

MalformedCookieException表示cookie的某些方面在给定的HTTP会话上下文中是无效或者非法的。有多种不兼容cookie规范,因此,cookie合法性建立在用于分析的特定cookie规范的上下文中和验证服务器发送cookie头消息。如果应用程序需要处理不常见的cookie规范定义的cookie,请查看cookie文档获取更多的信息。 

 

org.apache.commons.httpclient.RedirectException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.ProtocolException  
  4.       +- org.apache.commons.httpclient.RedirectException  

RedirectException表示一个无效的重定向响应导致了HTTP规范冲突。如果使用HttpClient的应用程序就重定向需要更多的宽松度的话,它可以选择禁用自动重定向处理和实现自定义重定向策略。 

 

org.apache.commons.httpclient.URIException 

  1. java.io.IOException  
  2.   +- org.apache.commons.httpclient.HttpException  
  3.     +- org.apache.commons.httpclient.URIException  

URIException表示请求的URL不符合URI规范。 

 

HTTP传输安全 

有必要了解是HTTP协议并不适用于所有类型的应用程序。HTTP是一个简单的面向requestre/sponse的协议,协议最初设计为支持静态或动态生成的内容检索。它从未打算支持事务性操作。例如,如果HTTP服务器成功接收和处理该请求,HTTP服务器会考虑其履行契约的一部分,生成响应和发送状态码回客户端。如果客户端由于读取超时,请求取消,或者系统崩溃而导致读取整个响应失败,服务器将不试图回滚事务。如果客户端重新发送同一请求,服务器将最终无可避免再一次执行同一事务。在某些情况下,将有可能导致应用程序数据的损坏或程序状态的不一致。 

即使HTTP从未被设计为支持事务性处理,它还是可以用作满足某些条件关键应用程序传输协议。为确保HTTP传输层安全系统必须确保应用层上的HTTP方法是幕等的。 

幕等方法 

HTTP/1.1规范定义幕等方法为: 

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. 

换句话说,应用程序应该确保它准备处理同一个的方法的多次执行带来的影响。这可以做到的,例如,通过提供一个唯一的事务id和通过其他方式避免执行相同的逻辑操作。 

需要注意的,这是问题并非特定于HttpClient。基于浏览器的应用程序在涉及到非幕等HTTP方法时,也会面临同样的问题。 

 

自动异常恢复 

默认情况下HttpClient尝试从异常中自动恢复。默认的自动恢复机制仅限于少数的几个已知安全的异常。HttpClient不会尝试从任何逻辑或是HTTP协议错误(HttpException派生的异常类)中恢复。 

HttpClient将最多5次自动重试因传输异常失败的方法,虽然请求仍被传输到目标服务器(也就是说,请求尚未完全传送到服务器)。 

HttpClient将最多自动重试那些方法5次,直到请求完全传送到服务器,但该服务器没有响应的HTTP状态代码(服务器只是简单的丢弃连接而没有发回任何响应)。在这种情况下则假定请求未被服务器处理和应用程序状态没有改变。如果web服务器应用程序目标的假设不成立,那么极力建议您提供自定义的异常处理程序。 

 

自定义异常处理类 

为了启用自定义异常的恢复机制应提供HttpMethodRetryHandler接口的实现。 

 

HttpClient client = new HttpClient();

HttpMethodRetryHandler myretryhandler = new HttpMethodRetryHandler() {
    public boolean retryMethod(
        final HttpMethod method, 
        final IOException exception, 
        int executionCount) {
        if (executionCount >= 5) {
            // Do not retry if over max retry count
            return false;
        }
        if (exception instanceof NoHttpResponseException) {
            // Retry if the server dropped connection on us
            return true;
        }
        if (!method.isRequestSent()) {
            // Retry if the request has not been sent fully or
            // if it's OK to retry methods that have been sent
            return true;
        }
        // otherwise do not retry
        return false;
    }
};
        
GetMethod httpget = new GetMethod("http://www.whatever.com/");
httpget.getParams().
    setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler);
try {
    client.executeMethod(httpget);
    System.out.println(httpget.getStatusLine().toString());
} finally {
    httpget.releaseConnection();
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用 HttpClient 进行网络请求时,可能会遇到超时异常。处理超时异常的方法有以下几种: 1. 设置超时时间:在创建 HttpClient 实例时,可以设置连接超时时间和读取超时时间,以确保请求在规定时间内得到响应。例如: ``` RequestConfig config = RequestConfig.custom() .setConnectTimeout(5000) // 连接超时时间为5秒 .setSocketTimeout(5000) // 读取超时时间为5秒 .build(); CloseableHttpClient httpClient = HttpClients.custom() .setDefaultRequestConfig(config) .build(); ``` 2. 使用连接池:使用连接池可以提高 HttpClient 的性能和稳定性,同时也可以减少超时异常的发生。例如: ``` PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(100); // 最大连接数为100 connManager.setDefaultMaxPerRoute(20); // 每个路由的最大连接数为20 CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(connManager) .build(); ``` 3. 重试机制:在请求失败时,可以进行重试,以增加请求成功的概率。例如: ``` HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { if (executionCount >= 3) { // 最多重试3次 return false; } if (exception instanceof InterruptedIOException) { // 超时异常 return true; } if (exception instanceof UnknownHostException) { // 未知主机异常 return false; } if (exception instanceof ConnectTimeoutException) { // 连接超时异常 return true; } if (exception instanceof SSLException) { // SSL异常 return false; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) { // 幂等请求 return true; } return false; } }; CloseableHttpClient httpClient = HttpClients.custom() .setRetryHandler(retryHandler) .build(); ``` 以上是处理 HttpClient 超时异常的几种方法,具体选择哪种方法,需要根据实际情况进行判断。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值