Apache Client使用说明第一章(第二部分)

1.2  HttpClient接口

HttpClient接口代表了HTTP请求执行最重要的约定.它规定了请求执行过程无任何和限制或者特定的细节以及审阅连接管理,状态管理,认证和重定向处理的实现等细节.这使得装饰接口附加功能更容易比如响应内容的缓存.

通常HttpClient的实现只是作为样子,大量特殊目的的处理器或策略接口的实现来处理HTTP协议具体的各个方面比如重定向或者认证的处理或者决定连接持续的时间.这使得用户可以替换某些默认的实现.

ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy(){
    public long getKeepAliveDuration(HttpResponse response, HttpContext context){
        long keepAlive = super.getKeepAliveDuration(response,context);
        if(keepAlive == -1) {
            //Keep connections alive 5 seconds if keep-alive value
            //has not be explicitly set by the server
            keepAlive = 5000;
        }
        return keepAlive;
    }
};

CloseableHttpClient httpclient = HttpClients.custom().setKeepAliveStrategy(keepAliveStrat).build();

1.2.1  HttpClient线程安全

HttpClient实现可以认为是线程安全的.推荐对于多次请求的执行使用该类的同一个实例.

1.2.2

HttpClient资源的解除

当CloseableHttpClient实例不在使用且超出该示例相关的连接管理的作用域是必须通过调用CloseableHttpClient#close()方法关闭.

CloseableHttpClient httpclient = HttpClients.createDefault();
try {
    <...>
} finally {
    httpclient.close();
}

1.3  HTTP执行上下文

最初的HTTP被设计成无状态的,响应请求导向协议.然而真实环境中的应用经常需要通过多个逻辑上关联的请求响应交互保存状态信息.为了是程序能够保持处理状态HttpClient允许HTTP请求在特定的上下文中执行.当同一个上下文被一系列的请求复用,逻辑关联的请求将共享一个逻辑上的session.HTTP上下文功能类似于java.util.Map<String,Object>.一个简单的键值对集合.应用程序可以在执行时填充上下文或者在执行完成后检查上下文.

HttpContext可以包含任意的对象因此在多个线程共享是不保证线程安全.推荐每个线程位置自己的上下文.

在HTTP请求执行过程中HttpClient添加以下上下文属性:

HttpConnection 代表实际抵达目标服务器的连接.

HttpHost 代表连接的目标

HttpRoute 代表完整的连接路由

HttpRequest 代表实际的HTTP请求.最终的HttpRequest对像始终表示消息已被发送到目标服务器的状态.默认的HTTP/1.0和HTTP1.1使用相对请求URI.但是如果请求通过非隧道模式的代理发送则URI是绝对的.

HttpResponse 代表示例的HTTP响应

java.lang.Boolean 代表请求是否完全的传送到连接的目标.

RequestConfig 代表实际的请求设置.

java.util.List<URI> 代表在请求执行过程中接收到的所有重定向位置集合

可以使用HttpClientContext适配类来简化上下文之间的差异.

HttpContext context = <...>;
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpHost target = clientContext.getTargetHost();
HttpRequest request = clientContext.getRequest();
HttpResponse response = clientContext.getResponse();
RequestConfig config = clientContext.getRequestConfig();

代表一个逻辑上相关的会话的请求序列应该用相同的HttpContext实例执行以确保上下文和状态信息在请求间的共享.

在接下来的示例中由初始请求配置将在执行上下文中保持并共享给其他相同上下文中的请求.

CloseableHttpClient httpclient = HttpClients.createDefault();
RequestConfig requestConfig = ReuestConfig.custom().setSocketTimeout(1000).setConnectTimeout(1000).build();
HttpGet httpget1 = new HttpGet();
httpget1.setConfig(requestConfig);
CloseableHttpResponse response1 = httpclient.execute(httpget1,context);
try {
    HttpEntity entity1 = response1.getEntity();
} finally {
    response1.close();
}

HttpGet httpget2 = new HttpGet();
httpget2.setConfig(requestConfig);
CloseableHttpResponse response1 = httpclient.execute(httpget2,context);
try {
    HttpEntity entity1 = response1.getEntity();
} finally {
    response1.close();
}

1.4  HTTP协议拦截器

HTTP请求拦截器是HTTP协议具体的常规实现.一般协议拦截预期作用在传入消息一个特定的头部或一组相关的头部.协议拦截器也可以操作消息封装的实体内容-传输内容的压缩和解压是最好的例子.这通常可以使用装饰器模式包装原有实体来完成.多个协议拦截器可以被组成一个逻辑单元.

协议拦截器可以通过共享信息合作-比如处理状态-通过HTTP执行上下文.协议拦截器可以存储一个或一系列请求的处理状态.通常这种拦截器的执行顺序并不重要,只要他们不依赖执行上下文的状态.如果协议拦截具有相互依赖关系而必须以特定顺序执行,则应保证添加的顺序与预期执行的顺序一致.

协议拦截器必须为线程安全的实现.与servlet类似,协议拦截器不应该使用实例变量除非对这些变量进行同步.

下面的例子展示上下文如何用于维持一系列请求的处理状态:

CloseableHttpClient httpclient = HttpClients.custom().addInterceptorLast(new HttpRequestInterceptor(){
    public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException{
        AtomicInteger count = (AtomicInteger)context.getAttribute("count");
    }
}).build();

AtomicInteger count = new AtomicInteger(1);
HttpClientContext localContext = HttpClientContext.create();
localContext.setAttribute("count",count);

HttpGet httpget = new HttpGer("");
for(int i = 0; i < 10; i++){
    CloseableHttpResponse response = httpclient.execute(httpget, localContext);
    try{
        HttpEntity entity = response.getEntity();
    } finally {
        response.close();
    }
}

1.5  异常处理

HTTP协议的处理这可能抛出两种类型的异常:java.io.IOException 表示I/O失败比如套接字超时或套接字重置,HttpException表示HTTP失败比如违背了HTTP协议.通常I/O错误是非致命和可恢复,然而HTTP协议错误是致命的且无法自动恢复.请注意HttpClient的实现会重新用java.io.IOException的子类ClientProtocolException抛出HttpException.用户可以在同一个catch代码块中处理I/O错误和协议错误.

1.5.1  HTTP传输安全

1.5.2  幂等方法

1.5.3  异常自动恢复

默认的HttpClient试图自动从I/O异常中恢复.默认的自动恢复机制只能处理一小部分异常.

HttpClient不会尝试从任何逻辑或HTTP协议错误中恢复(继承自HttpException类).

HttpClient将自动重试被认定的幂等方法.

HttpClient将自动重试当HTTP请求仍然在传输到目标服务器失败的方法(比如请求还没有完全传输到服务器).

1.5.4  请求重试处理方法

HttpRequestRetryHandler接口的实现用于自定义异常回复机制.

HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler(){
    public boolean retryRequest(IOException exception, int executionCouont, HttpContext context){
        if(executionCount >= 5){
            return false;
        }
        if(exception instanceof InterruptedIOException){
            return false;
        }
        if(exception instanceof UnknownHostException){
            return false;
        }
        if(exception instanceof ConnecTimeoutException){
            return false;
        }
        if(exception instanceof SSLException){
            return false;
        }
        HttpClientContext clientContext = HttpClientContext.adapt(context);
        HttpRequest request = clientContext.getRequest();
        boolean idmpotent - !(request instanceof HttpEntityEnclosingRequest);
        if(idempotent){
            return true;
        }
        return false;
    }
};
CloseableHttpClient httpclient = HttpClients.custom().setRetryHandler(myRetryHandler).build();

请注意可以使用StandardHttpRequestRetryHandler替代默认配置以便RFC-2616定义的幂等方法可以安全的自动重试:GET,HEAD,PUT,DELTE,OPTIONS和TRACE.

1.6  终止请求

在某些情况下HTTP请求可能由于目标服务器高负荷或者客户端有太多的请求在使用导致请求在预期的时间范围内执行失败.在这种情况下可能有必要提前终止该请求并解除执行线程对I/O操作的阻塞.通过HttpClient执行的HTTP请求可以在执行的任何阶段调用HttpUriRequest#abort()方法终止.该方法是线程安全的可以从任何线程调用.当HTTP请求终止执行现场-即使当前阻塞的I/O操作-通过抛出InterruptedIOException保证解除.

1.7  重定向处理

HttpClient自动处理所有类型的重定向,除了那些HTTP规范要求必须用户介入.POST和PUT请求的see Other(状态code 303)重定向按HTTP规范的要求转换成GET请求.可以自定义重定向策略覆盖HTTP规范规定的方式.

LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
CloseableHttpClient httpclient = HttpClients.custom().setRedirectStrategy(redirectStrategy).build();

HttpClient经常需要在执行过程中重写请求信息.默认的HTTP/1.0和HTTP/1.1通常使用相对请求URIS.同样,原始的请求也可能从其他位置重定向多次.最总的绝对HTTP位置可使用原始的请求和上下文获得.工具方法URIUtils#resolve可以用来解释绝对URI用于最终的请求.该方法包括重定向请求或原始请求的最后一个片段标识符.

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet();
CloseableHttpResponse response = httpclient.execute(httpget,context);
try{
    HttpPost target = context.getTargetHost();
    List<URI> redirectLocations = context.getRedirectLocations();
    URI location = URIUtils.resolve(httpget.getURI(),target,redirectLocations);
    System.out.println("Final HTTP location: " + location.toASCIIString());
} finally {
    response.close();
}
时间: 2024-08-02 22:15:18

Apache Client使用说明第一章(第二部分)的相关文章

Apache Client使用说明第一章(第一部分)

第一章.基础 1.1  请求的执行 HttpClient最重要的函数是用于执行HTTP方法.执行一次HTTP方法包涵一次或数次HTTP请求和HTTP响应的交互,通常在httpClient内部完成.程序员只需要提供一个请求对象用于执行,HttpClient发送请求道目标服务器并获得对应的响应对象,或者在执行不成功时抛出异常. HttpClient API的只要入口点是HttpClient接口. 以下是请求执行处理过程的简单示例 CloseableHttpClient httpclient = Ht

《Hadoop权威指南》笔记 第一章&第二章

? ? ? ? ? ? ? ? ? ? ? ? ? ? 使用MapReduce ? ? ? ? ? ? ? ? import java.io.IOException; // 是hadoop针对流处理优化的类型 import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; // 会继承这个基类 import org.apache

《Hadoop权威指南》笔记 第一章&第二章 MapReduce初探

? ? ? ? ? ? ? ? ? ? ? ? ? ? 使用MapReduce ? ? ? ? ? ? ? ? import java.io.IOException; // 是hadoop针对流处理优化的类型 import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; // 会继承这个基类 import org.apache

软件构造 第一章第二节 软件开发的质量属性

?软件构造 第一章第二节 软件开发的质量属性 1.软件系统质量指标 External quality factors affect users 外部质量因素影响用户 Internal quality factors affect the software itself and its developers 内部质量因素影响软件本身和它的开发者 External quality results from internal quality 外部质量取决于内部质量 外部属性: 正确性:按照预先定义的"

20172304 2018-2019《java软件结构与数据结构》 第一章 第二章学习总结

20172304 2018-2019<java软件结构与数据结构> 第一章 第二章学习总结 教材学习内容总结 第一章 概述 1.1软件质量: 高质量软件的几个特征: 正确性:软件在多大程度上满足其特定需求 可靠性:软件故障发生频率和危险程度 健壮性:出错情况下可以得到恰当处理的程度 可用性:用户学习和执行任务的难易程度 可维护性:对软件进行修改的难易程度 可重用性:软件组件可重用于其他软件系统开发的难易程度 可移植性:软件组件可以在多个计算机环境下使用的难易程度 运行效率:在不浪费资源的情况下

《淘宝技术这十年》读书笔记——第一章 第二章

引言 ? ? 这本书的作者是子柳先生,子柳本名赵超,2004年加入淘宝网.历任开发工程师.项目经理.产品经理.测试经理,2009年随着淘宝系统的大规模重构和人才的迅速扩张,创办了"淘宝技术大学",因培养内外部工程师众多,人称"校长". ? ? 之所以读这本书,主要想了解淘宝的技术/业务发展过程中遇到过哪些问题,以及他们怎么解决的.在阅读的过程中有很多不懂的地方,主要是知识面确实涵盖的太广,就当拓展视野吧. ? ? 第一章 ? ? 淘宝架构初版 ? ? 淘宝的第一版源

淘宝技术这十年 第一章 第二章

作者:子柳先生,本名赵超,2004年加入淘宝网,取花名子柳.历任开发工程师.项目经理.产品经理.测试经理,2009年随着淘宝系统的大规模重构和人才的迅速扩张,创办了"淘宝技术大学",培养内外部工程师众多,人称"校长". ? ? 这本书,主要想了解淘宝的技术/业务发展过程,遇到了哪些问题,怎么解决的.在阅读的过程中有很多不懂的地方,纯属拓展视野,的确如书中所说,不同阶段的读者会有不一样的收货,我也会不止一次的读下去的. ? ? 第一章 ? ? 淘宝的第一版源代码直接从

CSS3秘笈复习:第一章&amp;第二章&amp;第三章

第一章: 1.<cite>标签不仅可以将网页设置为斜体,还能给标题做上标记,使它便于被搜索引擎搜索到. 第二章: 1.import指令链接样式表: CSS本身有一种添加外部样式的方法:@import指令.把这个指令添加到一个HTML的<style>标签中,像这样: <style> @import url(css/styles.css); </style> 要将所有@import行都放在CSS规则之前. 第三章: 1.类选择器命名只允许使用字母数字连字符(-)

操作系统原理 第一章第二章复习

操作系统复习 第一章 操作系统概述 基本概念 吞吐量:单位时间内系统能处理的工作量. 进程:正在动态执行的程序 实时操作系系统:实时计算.计算的正确性不仅依赖于系统计算的逻辑结果,还依赖于产生这个结果的时间一类的计算. 操作系统的特征:现代操作系统大多支持多任务,具有并发.共享.虚拟.异步的特征. 单道批处理系统 特性:自动性.顺序性.单道性. 作业独占CPU和内存. 多道批处理系统 特性: 多道性.无序性.调度性.复杂性. 优点:提高CPU的利用率.提高内存和I/O设备的利用率.增加系统吞吐量