HttpClient异常处理手册

开源中国

发表于 2014-08-26 19:44:06

异常处理

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

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

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();
}

HttpClient异常处理手册的更多相关文章

  1. 点评阿里JAVA手册之异常日志(异常处理 日志规约 )

    下载原版阿里JAVA开发手册  [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:异常处理 日志规约 本文难度系数为一星(★) 本文为第三篇 ...

  2. Java开发最佳实践(二) ——《Java开发手册》之"异常处理、MySQL 数据库"

    二.异常日志 (一) 异常处理 (二) 日志规约 三.单元测试 四.安全规约 五.MySQL数据库 (一) 建表规约 (二) 索引规约 (三) SQL语句 (四) ORM映射 六.工程结构 七.设计规 ...

  3. 异常处理 - PHP手册笔记

    PHP代码中所产生的异常可被throw语句抛出,并被catch语句捕获.需要进行异常处理的代码都必须放入try代码块内,每一个try至少要有一个与之对应的catch.当一个异常被抛出时,所在代码块后面 ...

  4. Vert.x Core 文档手册

    Vert.x Core 文档手册 中英对照表 Client:客户端 Server:服务器 Primitive:基本(描述类型) Writing:编写(有些地方译为开发) Fluent:流式的 Reac ...

  5. [Java]使用HttpClient实现一个简单爬虫,抓取煎蛋妹子图

    第一篇文章,就从一个简单爬虫开始吧. 这只虫子的功能很简单,抓取到”煎蛋网xxoo”网页(http://jandan.net/ooxx/page-1537),解析出其中的妹子图,保存至本地. 先放结果 ...

  6. PHP错误以及异常处理

    以前一直觉得php的异常处理没有什么,现在才发现这个还真是门学问,于是狠下心来好好研究了一下,写一篇文章,也作备忘吧. 1. php错误 无论是什么语言编程,都会有如下三种错误,当然php也不例外. ...

  7. 《转载》Java异常处理的10个最佳实践

    本文转载自 ImportNew - 挖坑的张师傅 异常处理在编写健壮的 Java 应用中扮演着非常重要的角色.异常处理并不是功能性需求,它需要优雅地处理任何错误情况,比如资源不可用.非法的输入.nul ...

  8. mvc自定义全局异常处理

    异常信息处理是任何网站必不可少的一个环节,怎么有效显示,记录,传递异常信息又成为重中之重的问题.本篇将基于上篇介绍的html2cancas截图功能,实现mvc自定义全局异常处理.先看一下最终实现效果: ...

  9. springMVC、httpClient调用别人提供的接口!!!(外加定时调用)

    import com.ibm.db.util.AppConfig; import com.ibm.db.util.JacksonUitl; import org.apache.http.HttpEnt ...

随机推荐

  1. 42th-2

    '''   1, 元祖(2,3)'''def summ2(self, *args):    '''这是一个求一系列数平方和的函数'''    s = 0    for i in args:  #历遍元 ...

  2. Git中.gitignore文件不起作用

    Git中.gitignore文件不起作用的解决以及Git中的忽略规则介绍   在Studio里使用Git管理代码的过程中,可以修改.gitignore文件中的标示的方法来忽略开发者想忽略掉的文件或目录 ...

  3. C++在windows平台下不存在strptime函数,可以绕过该函数

    https://blog.csdn.net/u011077672/article/details/50524469?utm_source=blogxgwz1

  4. JavaSE---main方法解读

    1.概述 1.1 java程序入口:main方法 public static void main(String[] args){} a,public:java类由JVM调用,为了让JVM自由调用mai ...

  5. Selenium之XPATH定位方法

    转自 https://www.cnblogs.com/hanmk/p/8997786.html https://www.cnblogs.com/hanmk/p/9015502.html 感谢原作者 1 ...

  6. hdu1059&poj1014 Dividing (dp,多重背包的二分优化)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  7. 解决handsontable日期控件汉化的问题

    在项目的 node_modules\pikaday目录下打开 pikaday.js 把 i18n: { previousMonth : 'Previous Month', nextMonth : 'N ...

  8. [CSP-S模拟测试62]题解

    A.Graph 因为点可以随便走,所以对于每个联通块,答案为边数/2向下取整. 用类似Tarjan的方式,对于每个联通块建立一棵搜索树,尽量让每一个节点的儿子两两配对,如果做不到就用上头顶的天线. # ...

  9. ERROR in Error: ***Module is not an NgModule

    引入一个打包的模块时报了这个个错: $ rimraf out Done in 16.81s. lerna ERR! build Errored while running script in 'map ...

  10. flutter 接入阿里云OSS

    之前因为使用正常文件上传,用户多时拥堵无法正常上传,因此接入阿里OSS 来解决这个问题.本来打算整原生那块,看了下比较麻烦,用flutter dio 直接请求oss 完成 1.上传用到了image_p ...