场景:调用外部系统接口的http请求

要求:

1:可能是http请求,也可能是https请求

2:需要加入连接池的概念,不能每次发起请求都新建一个连接(每次连接握手三次,效率太低)

准备使用httpclient 4.5的版本

HTTPClient的特性

1. 基于标准、纯净的Java语言。实现了Http1.0和Http1.1

2. 以可扩展的面向对象的结构实现了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。

3. 支持HTTPS协议。

4. 通过Http代理建立透明的连接。

5. 利用CONNECT方法通过Http代理建立隧道的https连接。

6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos认证方案。

7. 插件式的自定义认证方案。

8. 便携可靠的套接字工厂使它更容易的使用第三方解决方案。

9. 连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。

10. 自动处理Set-Cookie中的Cookie。

11. 插件式的自定义Cookie策略。

12. Request的输出流可以避免流中内容直接缓冲到socket服务器。

13. Response的输入流可以有效的从socket服务器直接读取相应内容。

14. 在http1.0和http1.1中利用KeepAlive保持持久连接。

15. 直接获取服务器发送的response code和 headers。

16. 设置连接超时的能力。

17. 实验性的支持http1.1 response caching。

18. 源代码基于Apache License 可免费获取。

在HttpClient 4.x版本中引入了大量的构造器设计模式,很多的配置都不建议直接new出来,而且相关的API也有所改动,例如连接参数,以前是直接new出HttpConnectionParams对象后通过set方法逐一设置属性,现在有了构造器,可以通过如下方式进行构造:

  1. ConnectionConfig.custom().setCharset(Charsets.toCharset(defaultEncoding)).build();
  2. SocketConfig.custom().setSoTimeout(100000).build();

实现访问自签名https的要点就是建立一个自定义的SSLContext对象,该对象要有可以存储信任密钥的容器,还要有判断当前连接是否受信任的策略,以及在SSL连接工厂中取消对所有主机名的验证。他的代码将会在本文最后贴出来,以下代码均针对新HttpClient

首先建立一个信任任何密钥的策略。代码很简单,不去考虑证书链和授权类型,均认为是受信任的

  1. class AnyTrustStrategy implements TrustStrategy{  
    
        @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    return true;
    }
    }

HttpClient既能处理常规http协议,又能支持https,根源在于在连接管理器中注册了不同的连接创建工厂。当访问url的schema为http时,调用明文连接套节工厂来建立连接;当访问url的schema为https时,调用SSL连接套接字工厂来建立连接。对于http的连接我们不做修改,只针对使用SSL的https连接来进行自定义:

RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();  
ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
registryBuilder.register("http", plainSF);
//指定信任密钥存储对象和连接套接字工厂
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, new AnyTrustStrategy()).build();
LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
registryBuilder.register("https", sslSF);
} catch (KeyStoreException e) {
throw new RuntimeException(e);
} catch (KeyManagementException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
Registry<ConnectionSocketFactory> registry = registryBuilder.build();

在上述代码中可以看到,首先建立了一个密钥存储容器,随后让SSLContext开启TLS,并将密钥存储容器和信任任何主机的策略加载到该上下文中。构造SSL连接工厂时,将自定义的上下文和允许任何主机名通过校验的指令一并传入。最后将这样一个自定义的SSL连接工厂注册到https协议上。

前期准备已经完成,接下来我们要获得HttpClient对象:

//设置连接管理器
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
connManager.setDefaultConnectionConfig(connConfig);
connManager.setDefaultSocketConfig(socketConfig);
//构建客户端
HttpClient client= HttpClientBuilder.create().setConnectionManager(connManager).build();

为了让我们的HttpClient具有多线程处理的能力,连接管理器选用了PoolingHttpClientConnectionManager,将协议注册信息传入连接管理器,最后再次利用构造器的模式创建出我们需要的HttpClient。随后的GET/POST请求发起方法http和https之间没有差异。

HttpClient 基于连接池的使用的更多相关文章

  1. httpclient httpclient使用连接池

    httpclient使用连接池 http协议是无状态的,但毕竟是基于tcp的,底层还是需要和服务器连接的, 对于需要从同一个站点抓取大量网页的程序,应该使用连接池,否则每次抓取都和web站点建立连接, ...

  2. httpclient: 设置连接池及超时配置,请求数据:PoolingHttpClientConnectionManager

    public static void main(String[] args) throws Exception{ //httpclient连接池 //创建连接池 PoolingHttpClientCo ...

  3. Http持久连接与HttpClient连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  4. HttpClient实战二:单线程和多线程连接池实例

    为什么使用HTTP连接池? 随着系统架构风格逐渐向前后端分离架构,微服务架构转变,RestFul风格API的开发与设计,同时SpringMVC也很好的支持了REST风格接口.各个系统之间服务的调用大多 ...

  5. Http 持久连接与 HttpClient 连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  6. HttpClient连接池的一些思考

    前言 使用apache的httpclient进行http的交互处理已经很长时间了,而httpclient实例则使用了http连接池,想必大家也没有关心过连接池的管理.事实上,通过分析httpclien ...

  7. 基于HiKariCP组件,分析连接池原理

    HiKariCP作为SpringBoot2框架的默认连接池,号称是跑的最快的连接池,数据库连接池与之前两篇提到的线程池和对象池,从设计的原理上都是基于池化思想,只是在实现方式上有各自的特点:

  8. 带有连接池的Http客户端工具类HttpClientUtil

    一.背景 业务开发中,经常会遇到通过http/https向下游服务发送请求.每次都要重复造轮子写HttpClient的逻辑,而且性能.功能参差不齐.这里分享一个高性能的.带连接池的通用Http客户端工 ...

  9. 走进JavaWeb技术世界3:JDBC的进化与连接池技术

    走进JavaWeb技术世界3:JDBC的进化与连接池技术 转载公众号[码农翻身] 网络访问 随着 Oracle, Sybase, SQL Server ,DB2,  Mysql 等人陆陆续续住进数据库 ...

随机推荐

  1. Python数据分析 EPD

    参考用书 <利用Python进行技术分析:Python for Data Analysis> 官方把epd (https://www.enthought.com/products/cano ...

  2. quarz入门案例

    介绍 Quartz框架是一个全功能.开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统.Quartz可以执行上千上万的任务调度.   核心概念  Quartz ...

  3. Borland.Delphi.dll

    Borland.Delphi.dll Borland Delphi Runtime for .NET Imports Borland.DelphiImports Borland.Delphi.Unit ...

  4. Hadoop IO基于文件的数据结构详解【列式和行式数据结构的存储策略】

    Charles所有关于hadoop的文章参考自hadoop权威指南第四版预览版 大家可以去safari免费阅读其英文预览版.本人也上传了PDF版本在我的资源中可以免费下载,不需要C币,点击这里下载. ...

  5. Leetcode:Regular Expression Matching分析和实现

    题目大意是要求我们实现一个简单的正则表达式全匹配判断.其中正则表达式中只包含一般字符,以及全匹配字符.和变长字符*.其中.可以匹配一个字符,而*与前一个字符相关联,x*可以被看作任意多个x(0到正无穷 ...

  6. 02-nginx信号量

    刚才完了nginx的编译,nginx的编译还是挺简单的.控制nginx:重启.关闭.只有孤零零的一个二进制文件nginx 通过信号来控制它,Linux操作系统进程与进程之间通过信号来通信.荷兰的一位计 ...

  7. Professional C# 6 and .NET Core 1.0 - Chapter 38 Entity Framework Core

    本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - Chapter 38 Entity F ...

  8. php析构方法关于栈的问题

    <?php class test{ var $name; var $sex; var $age; function __construct( $name, $sex ,$age ) { $thi ...

  9. BeautifulSoup练习

    html1="""<!DOCTYPE html><html lang="en" xmlns="http://www.w3. ...

  10. Mac下MongoDB enterprise版的安装

    1. 访问mongodb下载中心,https://www.mongodb.com/download-center#enterprise,选择OS X x64系统,点击下载,可能会出一个页面让你填写联系 ...