本文出处:http://blog.csdn.net/chaijunkun/article/details/40145685,转载请注明。因为本人不定期会整理相关博文,会对相应内容作出完好。因此强烈建议在原始出处查看此文。

HttpClient在当今Java应用中的位置越来越重要。从该项目的变迁过程我们不难发现,其已经从apache-commons众多的子项目中剥离,一跃成为现在的顶级项目。可见它的分量。然而随着项目的升级和架构的调整。非常多曾经经常使用的类和方法都已被打上了@Deprecated注解,作为一个有代码洁癖的程序员。我们也有必要升级一下工具类,让代码更加整洁。

另外在项目中正好须要訪问https协议的接口。而相应的server没有购买商业CA颁发的正式受信证书,仅仅是做了个自签名(联想一下12306站点购票时提示的那个警告信息)。默认情况下通过HttpClient訪问会抛出异常,在本文中也给出了解决的方法。

在HttpClient 4.x版本号中引入了大量的构造器设计模式。非常多的配置都不建议直接new出来。并且相关的API也有所修改,比如连接參数,曾经是直接new出HttpConnectionParams对象后通过set方法逐一设置属性,现在有了构造器。能够通过例如以下方式进行构造:

ConnectionConfig.custom().setCharset(Charsets.toCharset(defaultEncoding)).build();

SocketConfig.custom().setSoTimeout(100000).build();

基本情况就是这样,接下来谈下怎样使用新的HttpClient来訪问自签名https接口。

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

首先建立一个信任不论什么密钥的策略。代码非常easy,不去考虑证书链和授权类型,均觉得是受信任的:

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之间没有差异。

为了验证我们的代码是否成功,能够做下JUnit单元測试:

@Test
public void doTest() throws ClientProtocolException, URISyntaxException, IOException{
HttpUtil util = HttpUtil.getInstance();
InputStream in = util.doGet("https://kyfw.12306.cn/otn/leftTicket/init");
String retVal = HttpUtil.readStream(in, HttpUtil.defaultEncoding);
System.out.println(retVal);
}

运行后能够在控制台看到12306余票查询界面的html代码

为了方便大家使用,本人将封装好的代码上传到了CSDN资源共享中,欢迎下载。

下载地址:http://download.csdn.net/detail/chaijunkun/8046331

最后感谢CSDN博主noodies的代码提供了思路:http://blog.csdn.net/noodies/article/details/17240805

本文中的部分代码參阅了HttpClient 4.3.5官方文档的2.7节关于Connection socket factories的内容

基于HttpClient 4.3的可訪问自签名HTTPS网站的新版工具类的更多相关文章

  1. HttpClient的Post和Get訪问网页

    一.基础JAR包 Mavenproject下pom.xml需配置的jar包 <dependencies> <dependency> <groupId>junit&l ...

  2. 利用httpclient和多线程刷訪问量代码

    缘起于玩唱吧,由于唱吧好友少,訪问量低,又不想加什么亲友团之类的,主要是太麻烦了,于是我就琢磨唱吧的訪问机制,准备用java的httpclient库来进行刷訪问量,想到动态IP反复使用就想到了用多线程 ...

  3. 使用FREDATED引擎实现跨实例訪问

    跨数据库server.跨实例訪问是比較常见的一种訪问方式,在Oracle中能够通过DB LINK的方式来实现. 对于MySQL而言,有一个FEDERATED存储引擎与之相相应.相同也是通过创建一个链接 ...

  4. 使用AXIS2作为Client訪问WebService

    使用AXIS2,能够方便的构建WebService的server端,也能够非常方便的作为Cilent,来訪问别的WebService. 以下依据工作中的经历,整理了一下,作为Cilent訪问WebSe ...

  5. C++类訪问控制及继承

    一.C++类的訪问控制有三类:public,protected和private. 类訪问控制符 类成员可被哪些对象訪问 public 1.类的成员函数.2.类对象.3.友元.4.子类成员函数 prot ...

  6. Objective-C 类属性和方法的訪问权限

    OC中提供了4种訪问权限.@private, @public, @protected这三种和其它的C++, Java是一样的,@package这个訪问权限并非Java里的包訪问权限,OC中没有包的概念 ...

  7. Java 訪问权限控制:你真的了解 protected keyword吗?

    摘要: 在一个类的内部,其成员(包含成员变量和成员方法)是否能被其它类所訪问,取决于该成员的修饰词:而一个类是否能被其它类所訪问,取决于该类的修饰词.Java的类成员訪问权限修饰词有四类:privat ...

  8. JAVA基础之訪问控制权限(封装)

    包:库单元 1.当编写一个Java源码文件时.此文件通常被称为编译单元(有时也被称为转译单元). 2.每一个编译单元都必须有一个后缀名.java,而在编译单元内则能够有一个public类,该类名称必须 ...

  9. 訪问控制 protected, public, private 对照

    OOP 3大特性:数据抽象,继承,动态绑定 3中訪问标号 protected, public, private 对照 用类进行数据抽象:用继承类继承基类的成员,实现继承.通过将基类对应函数声明为vir ...

随机推荐

  1. leetcode Sum Root to Leaf Numbers(所有路径之和)

    转载请注明来自souldak,微博:@evagle 观察题目给的返回值类型是int,可以断定这棵树的高度不会超过10,所以数据量其实是非常小的.那就直接dfs遍历这棵树,然后到叶子节点的时候将值加到最 ...

  2. ASP.NET - GridView实现点击编辑列

    加载: 点击编辑: 数据库设计: 前端代码: DataKeyNames="ID"  设置点击“编辑”选项的时候,要获取的值,一般获取ID主键,便于修改数据. AutoGenerat ...

  3. Eclipse在点击运行后不能自动保存的解决

    今天在eclipse上写程序调试时,发现当我点击运行按键之后,并不能在运行前帮我自动保存,也就是说每次修改代码之后, 运行的还是前一次运行之前的代码,并不是修改之后的代码,因此通过在网上搜索解决方案之 ...

  4. 积累的VC编程小技巧之按钮

    1.资源种创建的控件,对其属性的动态控制: 在对话框类的头文件里创建所要改变属性的控件的对象,如要改变一个Button(其ID为IDC_MyButton)的属性,则需创建Cbutton的对象m_but ...

  5. HDU 4707 Pet(DFS(深度优先搜索)+BFS(广度优先搜索))

    Pet Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissio ...

  6. MySQL 採用Xtrabackup对数据库进行全库备份

    1,xtrabackup简单介绍 关于数据库备份以及备份工具.參考:http://blog.itpub.net/26230597/viewspace-1460065/,这里来介绍xtrabackup已 ...

  7. Swift - 使用UIScrollView实现页面滚动切换

    UIScrollView提供了以页面为单位滚动显示各个子页面内容的功能,每次手指滑动后会滚动一屏的内容.   要实现该功能,需要如下操作: 1,将UIScrollView的pagingEnabled属 ...

  8. ADO面板上的控件简介

    ADO面板上的控件简介 一. TADOConnection组件该组件用于建立数据库的连接.ADO的数据源组件和命令组件可以通过该组件运行命令及数据库中提取数据等.该组件用于建立数据库的连接,该连接可被 ...

  9. Dom4j和Xpath(转)

    1.DOM4J简介 DOM4J是 dom4j.org 出品的一个开源 XML 解析包.DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和JAXP. DOM4J使 ...

  10. JSCapture实现屏幕捕捉

    JSCapture 是用纯 JavaScript 和 HTML5 实现的屏幕捕捉库. 能够随意在浏览器或者桌面视频进行截图, JSCapture 使用 getUserMedia 来实现屏幕捕获. 当前 ...