设为首页 加入收藏

TOP

HttpClient 教程(五)
2015-07-16 12:55:54 来源: 作者: 【 】 浏览:30
Tags:HttpClient 教程
on类中派生出的)中恢复的。
HttpClient将会自动重新执行那么假设是幂等的方法。
HttpClient将会自动重新执行那些由于运输异常失败,而HTTP请求仍然被传送到目标服务器(也就是请求没有完全被送到服务器)失败的方法。
HttpClient将会自动重新执行那些已经完全被送到服务器,但是服务器使用HTTP状态码(服务器仅仅丢掉连接而不会发回任何东西)响应时失败的方法。在这种情况下,假设请求没有被服务器处理,而应用程序的状态也没有改变。如果这个假设可能对于你应用程序的目标Web服务器来说不正确,那么就强烈建议提供一个自定义的异常处理器。
1.3.4 请求重试处理
为了开启自定义异常恢复机制,应该提供一个HttpRequestRetryHandler接口的实现。


DefaultHttpClient httpclient = new DefaultHttpClient();
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException exception,
int executionCount,HttpContext context) {
if (executionCount >= 5) {
// 如果超过最大重试次数,那么就不要继续了
return false;
}
if (exception instanceof NoHttpResponseException) {
// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {
// 不要重试SSL握手异常
return false;
}
HttpRequest request = (HttpRequest) context.getAttribute(
ExecutionContext.HTTP_REQUEST);
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// 如果请求被认为是幂等的,那么就重试
return true;
}
return false;
}
};
httpclient.setHttpRequestRetryHandler(myRetryHandler);
1.4 中止请求
在一些情况下,由于目标服务器的高负载或客户端有很多活动的请求,那么HTTP请求执行会在预期的时间框内而失败。这时,就可能不得不过早地中止请求,解除封锁在I/O执行中的线程封锁。被HttpClient执行的HTTP请求可以在执行的任意阶段通过调用HttpUriRequest#abort()方法而中止。这个方法是线程安全的,而且可以从任意线程中调用。当一个HTTP请求被中止时,它的执行线程就封锁在I/O操作中了,而且保证通过抛出InterruptedIOException异常来解锁。


1.5 HTTP协议拦截器
HTTP协议拦截器是一个实现了特定HTPP协议方面的惯例。通常协议拦截器希望作用于一个特定头部信息上,或者一族收到报文的相关头部信息,或使用一个特定的头部或一族相关的头部信息填充发出的报文。协议拦截器也可以操纵包含在报文中的内容实体,透明的内容压缩/解压就是一个很好的示例。通常情况下这是由包装器实体类使用了“装饰者”模式来装饰原始的实体完成的。一些协议拦截器可以从一个逻辑单元中来结合。


协议拦截器也可以通过共享信息来共同合作-比如处理状态-通过HTTP执行上下文。协议拦截器可以使用HTTP内容来为一个或多个连续的请求存储一个处理状态。


通常拦截器执行的顺序不应该和它们基于的特定执行上下文状态有关。如果协议拦截器有相互依存关系,那么它们必须按特定顺序来执行,正如它们希望执行的顺序一样,它们应该在相同的序列中被加到协议处理器。


协议拦截器必须实现为线程安全的。和Servlet相似,协议拦截器不应该使用实例变量,除非访问的那些变量是同步的。


这个示例给出了本地内容在连续的请求中怎么被用于持久一个处理状态的:


DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
AtomicInteger count = new AtomicInteger(1);
localContext.setAttribute(“count”, count);
httpclient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(final HttpRequest request,
final HttpContext context) throws HttpException, IOException {
AtomicInteger count = (AtomicInteger) context.getAttribute(“count”);
request.addHeader(“Count”, Integer.toString(count.getAndIncrement()));
}
});
HttpGet httpget = new HttpGet(“http://localhost/”);
for (int i = 0; i < 10; i++) {
HttpResponse response = httpclient.execute(httpget, localContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
entity.consumeContent();
}
}
1.6 HTTP参数
HttpParams接口代表了定义组件运行时行为的一个不变的值的集合。很多情况下,HttpParams和HttpContext相似。二者之间的主要区别是它们在运行时使用的不同。这两个接口表示了对象的集合,它们被视作为访问对象值的键的Map,但是服务于不同的目的:


HttpParams旨在包含简单对象:整型,浮点型,字符串,集合,还有运行时不变的对象。
HttpParams希望被用在“一次写入-多处准备”模式下。HttpContext旨在包含很可能在HTTP报文处理这一过程中发生改变的复杂对象
HttpParams的目标是定义其它组件的行为。通常每一个复杂的组件都有它自己的HttpParams对象。HttpContext的目标是来表示一个HTTP处理的执行状态。通常相同的执行上下文在很多合作的对象中共享。
1.6.1 参数层次
在HTTP请求执行过程中,HttpRequest对象的HttpParams是和用于执行请求的HttpClient实例的HttpParams联系在一起的。这使得设置在HTTP请求级别的参数优先于设置在HTTP客户端级别的HttpParams。推荐的做法是设置普通参数对所有的在HTTP客户端级别的HTTP请求共享,而且可以选择性重写具体在HTTP请求级别的参数。


DefaultHttpClient httpclient = new DefaultHttpClient();
httpcl

首页 上一页 2 3 4 5 6 下一页 尾页 5/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Spring REST 异常处理 下一篇使用HttpClient4来构建Spring Res..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: