HttpClient学习研究---第七章:高级主题

来源:互联网 发布:ppt 数据展示 编辑:程序博客网 时间:2024/04/30 19:12

第7章。Advanced topics高级主题

7.1.7.1。Custom client connections定制客户端连接

In certain situations it may be necessary to customize the way HTTP messages get transmitted across the wire beyond what is possible using HTTP parameters in order to be able to deal non-standard, non-compliant behaviours.在某些情况下可能需要定制HTTP消息的方式传播整个线超出使用HTTP参数是可能为了能够交易不规范,不一致的行为。For instance, for web crawlers it may be necessary to force HttpClient into accepting malformed response heads in order to salvage the content of the messages.例如,对于web爬虫程序可能需要力HttpClient接受畸形的响应头为了救助信息的内容。

Usually the process of plugging in a custom message parser or a custom connection implementation involves several steps:通常的过程中插入一个自定义消息解析器或一个自定义连接的实现涉及几个步骤:

  • Provide a custom提供一个自定义 LineParser / LineFormatterinterface implementation.接口的实现。Implement message parsing / formatting logic as required.实现消息解析/格式化逻辑的要求。

    class MyLineParser extends BasicLineParser {    @Override    public Header parseHeader(            CharArrayBuffer buffer) throws ParseException {        try {            return super.parseHeader(buffer);        } catch (ParseException ex) {            // Suppress ParseException exception            return new BasicHeader(buffer.toString(), null);        }    }}
  • Provide a custom提供一个自定义 HttpConnectionFactoryimplementation.实现。Replace default request writer and / or response parser with custom ones as required.替换默认请求作家和/或响应的解析器和自定义的要求。

    HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory =        new ManagedHttpClientConnectionFactory(            new DefaultHttpRequestWriterFactory(),            new DefaultHttpResponseParserFactory(                    new MyLineParser(), new DefaultHttpResponseFactory()));
  • Configure HttpClient to use the custom connection factory.以使用自定义配置HttpClient连接工厂。

    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(    connFactory);CloseableHttpClient httpclient = HttpClients.custom()        .setConnectionManager(cm)        .build();

7.2.7.2。Stateful HTTP connections有状态的HTTP连接

While HTTP specification assumes that session state information is always embedded in HTTP messages in the form of HTTP cookies and therefore HTTP connections are always stateless, this assumption does not always hold true in real life. 虽然HTTP规范假定会话状态信息通常是嵌入在HTTP消息的形式,HTTP cookies,因此HTTP连接总是无状态,这种假设并不总是适用在现实生活中。There are cases when HTTP connections are created with a particular user identity or within a particular security context and therefore cannot be shared with other users and can be reused by the same user only. 有一些情况下,创建HTTP连接与一个特定的用户身份或在一个特定的安全上下文,因此不能与其他用户共享,可以重用相同的用户只有。Examples of such stateful HTTP connections are这样的例子有状态的HTTP连接是 NTLMauthenticated connections and SSL connections with client certificate authentication.身份验证的连接和SSL连接的客户端证书身份验证。

7.2.1.7.2.1。User token handler用户标记处理程序

HttpClient relies onHttpClient依赖 UserTokenHandlerinterface to determine if the given execution context is user specific or not.接口来确定给定的执行上下文是用户特定的或不是。The token object returned by this handler is expected to uniquely identify the current user if the context is user specific or to be null if the context does not contain any resources or details specific to the current user. 令牌对象返回的这个处理程序将惟一地标识当前用户如果上下文是用户特定的或者是null如果上下文不包含任何资源或细节具体到当前用户。The user token will be used to ensure that user specific resources will not be shared with or reused by other users.用户令牌将被用于确保用户特定的资源不会被共享或重用被其他用户。

The default implementation of the默认的实现 UserTokenHandlerinterface uses an instance of Principal class to represent a state object for HTTP connections, if it can be obtained from the given execution context.接口使用的一个实例,主要类表示一个状态对象对HTTP连接,如果它可以获得给定的执行上下文。 DefaultUserTokenHandlerwill use the user principle of connection based authentication schemes such as将使用用户身份验证方案的原理基于连接如 NTLMor that of the SSL session with client authentication turned on.或SSL会话与客户机身份验证打开。If both are unavailable, null token will be returned.如果两者都不可用,空令牌将被返回。

CloseableHttpClient httpclient = HttpClients.createDefault();HttpClientContext context = HttpClientContext.create();HttpGet httpget = new HttpGet("http://localhost:8080/");CloseableHttpResponse response = httpclient.execute(httpget, context);try {    Principal principal = context.getUserToken(Principal.class);    System.out.println(principal);} finally {    response.close();}

Users can provide a custom implementation if the default one does not satisfy their needs:用户可以提供一个自定义实现如果默认不满足他们的需求:

UserTokenHandler userTokenHandler = new UserTokenHandler() {    public Object getUserToken(HttpContext context) {        return context.getAttribute("my-token");    }};CloseableHttpClient httpclient = HttpClients.custom()        .setUserTokenHandler(userTokenHandler)        .build();

7.2.2.7 2 2。Persistent stateful connections持久有状态连接

Please note that a persistent connection that carries a state object can be reused only if the same state object is bound to the execution context when requests are executed.请注意,持久连接,携带一个状态对象可以被重用,只有在同一状态对象被绑定到请求时执行执行上下文。So, it is really important to ensure the either same context is reused for execution of subsequent HTTP requests by the same user or the user token is bound to the context prior to request execution.因此,它是非常重要的,确保要么是重用同一上下文中执行后续的HTTP请求相同的用户或用户令牌绑定到上下文请求执行之前。

CloseableHttpClient httpclient = HttpClients.createDefault();HttpClientContext context1 = HttpClientContext.create();HttpGet httpget1 = new HttpGet("http://localhost:8080/");CloseableHttpResponse response1 = httpclient.execute(httpget1, context1);try {    HttpEntity entity1 = response1.getEntity();} finally {    response1.close();}Principal principal = context1.getUserToken(Principal.class);HttpClientContext context2 = HttpClientContext.create();context2.setUserToken(principal);HttpGet httpget2 = new HttpGet("http://localhost:8080/");CloseableHttpResponse response2 = httpclient.execute(httpget2, context2);try {    HttpEntity entity2 = response2.getEntity();} finally {    response2.close();}

7.3.7.3。Using the FutureRequestExecutionService使用FutureRequestExecutionService

Using the FutureRequestExecutionService, you can schedule http calls and treat the response as a Future.使用FutureRequestExecutionService,可以调度http调用和治疗反应作为一个未来。This is useful when e.g. making multiple calls to a web service.这是有用,当如使多个调用web服务。The advantage of using the FutureRequestExecutionService is that you can use multiple threads to schedule requests concurrently, set timeouts on the tasks, or cancel them when a response is no longer necessary.使用FutureRequestExecutionService的优势是,您可以使用多个线程并发调度要求,设置超时的任务,或取消他们当一个响应不再是必要的。

FutureRequestExecutionService wraps the request with a HttpRequestFutureTask, which extends FutureTask.FutureRequestExecutionService包装了的请求与HttpRequestFutureTask延伸FutureTask。This class allows you to cancel the task as well as keep track of various metrics such as request duration.这个类允许你取消任务以及跟踪各种指标如请求持续时间。

7.3.1.7.3.1。Creating the FutureRequestExecutionService创建FutureRequestExecutionService

The constructor for the futureRequestExecutionService takes any existing httpClient instance and an ExecutorService instance.的构造函数futureRequestExecutionService需要任何现有的实例和一个ExecutorService httpClient实例。When configuring both, it is important to align the maximum number of connections with the number of threads you are going to use.当配置两个,重要的是要调整的最大连接数与线程的数量你要使用。When there are more threads than connections, the connections may start timing out because there are no available connections.当有更多的线程连接,连接超时可能会因为没有可用的连接。When there are more connections than threads, the futureRequestExecutionService will not use all of them当有更多的连接比线程,futureRequestExecutionService不会使用他们

HttpClient httpClient = HttpClientBuilder.create().setMaxConnPerRoute(5).build();ExecutorService executorService = Executors.newFixedThreadPool(5);FutureRequestExecutionService futureRequestExecutionService =    new FutureRequestExecutionService(httpClient, executorService);

7.3.2.7 3 2。Scheduling requests调度请求

To schedule a request, simply provide a HttpUriRequest, HttpContext, and a ResponseHandler.安排一个请求,只需提供一个HttpUriRequest,HttpContext,ResponseHandler。Because the request is processed by the executor service, a ResponseHandler is mandatory.因为请求处理执行器服务,一个ResponseHandler是强制性的。

private final class OkidokiHandler implements ResponseHandler<Boolean> {    public Boolean handleResponse(            final HttpResponse response) throws ClientProtocolException, IOException {        return response.getStatusLine().getStatusCode() == 200;    }}HttpRequestFutureTask<Boolean> task = futureRequestExecutionService.execute(    new HttpGet("http://www.google.com"), HttpClientContext.create(),    new OkidokiHandler());// blocks until the request complete and then returns true if you can connect to Googleboolean ok=task.get();

7.3.3.7 3 3。Canceling tasks取消任务

Scheduled tasks may be cancelled. 调度的任务可能被取消。If the task is not yet executing but merely queued for execution, it simply will never execute.如果任务没有执行但只是排队等待执行,它只是永远不会执行。If it is executing and the mayInterruptIfRunning parameter is set to true, abort() will be called on the request; otherwise the response will simply be ignored but the request will be allowed to complete normally. 如果是执行和mayInterruptIfRunning参数设置为true,将调用abort()请求,否则反应只会被忽略但请求将被允许完全正常。Any subsequent calls to task.get() will fail with an IllegalStateException.任何后续调用任务得到()将失败与IllegalStateException。It should be noticed that canceling tasks merely frees up the client side resources.应该注意到,取消任务只是腾出了客户端资源。The request may actually be handled normally on the server side.请求实际上可能是通常在服务器端处理。

task.cancel(true)task.get() // throws an Exception

7.3.4.7 3 4。Callbacks回调

Instead of manually calling task.get(), you can also use a FutureCallback instance that gets callbacks when the request completes.代替手动调用任务得到(),您还可以使用一个回调FutureCallback实例,得到当请求完成。This is the same interface as is used in HttpAsyncClient这是相同的接口是用于HttpAsyncClient

private final class MyCallback implements FutureCallback<Boolean> {    public void failed(final Exception ex) {        // do something    }    public void completed(final Boolean result) {        // do something    }    public void cancelled() {        // do something    }}HttpRequestFutureTask<Boolean> task = futureRequestExecutionService.execute(    new HttpGet("http://www.google.com"), HttpClientContext.create(),    new OkidokiHandler(), new MyCallback());

7.3.5.7 3 5。Metrics指标

FutureRequestExecutionService is typically used in applications that make large amounts of web service calls.FutureRequestExecutionService通常用于应用程序,使大量的web服务调用。To facilitate e.g. monitoring or configuration tuning, the FutureRequestExecutionService keeps track of several metrics.促进如监测或配置调优,FutureRequestExecutionService跟踪几个指标。

Each HttpRequestFutureTask provides methods to get the time the task was scheduled, started, and ended.每个HttpRequestFutureTask提供方法来获取时间任务计划,开始和结束。Additionally, request and task duration are available as well.此外,请求和任务持续时间也可用。These metrics are aggregated in the FutureRequestExecutionService in a FutureRequestExecutionMetrics instance that may be accessed through FutureRequestExecutionService.metrics().这些指标在FutureRequestExecutionService聚集在一个FutureRequestExecutionMetrics实例都可以访问通过FutureRequestExecutionService.metrics()。

task.scheduledTime() // returns the timestamp the task was scheduledtask.startedTime() // returns the timestamp when the task was startedtask.endedTime() // returns the timestamp when the task was done executingtask.requestDuration // returns the duration of the http requesttask.taskDuration // returns the duration of the task from the moment it was scheduledFutureRequestExecutionMetrics metrics = futureRequestExecutionService.metrics()metrics.getActiveConnectionCount() // currently active connectionsmetrics.getScheduledConnectionCount(); // currently scheduled connectionsmetrics.getSuccessfulConnectionCount(); // total number of successful requestsmetrics.getSuccessfulConnectionAverageDuration(); // average request durationmetrics.getFailedConnectionCount(); // total number of failed tasksmetrics.getFailedConnectionAverageDuration(); // average duration of failed tasksmetrics.getTaskCount(); // total number of tasks scheduledmetrics.getRequestCount(); // total number of requestsmetrics.getRequestAverageDuration(); // average request durationmetrics.getTaskAverageDuration(); // average task duration
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机接听声音小怎么办 微信账号封了怎么办 在京东买的手机出现问题怎么办 销售没胆量扫楼怎么办 骨龄比实际年龄小怎么办 身体年龄比实际年龄大怎么办 吃了不熟的鸡蛋怎么办 六角龙尾巴烂了怎么办 兰花长出来的包怎么办 长寿花花开败了怎么办 手机分期0首付怎么办办 办分期手机掉了怎么办 手机办分期被骗了怎么办 办手机分期年龄不够怎么办 信美分期没额度怎么办 家里人不给我钱怎么办 商场租金收不上来怎么办 魅蓝2电池坏了怎么办 格力空调不制冷怎么办 空调外机不好放怎么办 美的空调显示e3怎么办 发现安装空调条码被撕怎么办 删除了国美安装码怎么办 海信空调保修卡丢了怎么办 海尔空调保修卡丢了怎么办 科龙空调不制冷怎么办 魅族s6屏幕碎了怎么办 格力空调化霜怎么办 一开空调就跳闸怎么办 洗衣机顶盖的安全开关损坏怎么办 苹果平板电脑拍照坏了怎么办 苹果hom键不灵了怎么办 平板电脑home键发烫怎么办 华为平板无法输入资料怎么办 安卓平板没声音怎么办? 平果手机充不了电怎么办 苹果6s用电太快怎么办 平板充不起电了怎么办 日本买的电器国内售后怎么办 海淘地址试投不成功怎么办 怀孕了吐得厉害怎么办