HttpClient实现https调用
在HttpClient 4.x版本中引入了大量的构造器设计模式
https请求建立详解
首先建立一个信任任何密钥的策略。代码很简单,不去考虑证书链和授权类型,均认为是受信任的:
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 registryBuilder = RegistryBuilder.create();
ConnectionSocketFactory plainSF =newPlainConnectionSocketFactory();
registryBuilder.register("http", plainSF);
//指定信任密钥存储对象和连接套接字工厂
try{
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore,newAnyTrustStrategy()).build();
LayeredConnectionSocketFactory sslSF =newSSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
registryBuilder.register("https", sslSF);
}catch(KeyStoreException e) {
thrownewRuntimeException(e);
}catch(KeyManagementException e) {
thrownewRuntimeException(e);
}catch(NoSuchAlgorithmException e) {
thrownewRuntimeException(e);
}
Registry registry = registryBuilder.build();
在上述代码中可以看到,首先建立了一个密钥存储容器,随后让SSLContext开启TLS,并将密钥存储容器和信任任何主机的策略加载到该上下文中。构造SSL连接工厂时,将自定义的上下文和允许任何主机名通过校验的指令一并传入。最后将这样一个自定义的SSL连接工厂注册到https协议上。
//设置连接管理器
PoolingHttpClientConnectionManager connManager =newPoolingHttpClientConnectionManager(registry);
connManager.setDefaultConnectionConfig(connConfig);
connManager.setDefaultSocketConfig(socketConfig);
//构建客户端
HttpClient client= HttpClientBuilder.create().setConnectionManager(connManager).build();
为了让我们的HttpClient具有多线程处理的能力,连接管理器选用了PoolingHttpClientConnectionManager,将协议注册信息传入连接管理器,最后再次利用构造器的模式创建出我们需要的HttpClient。随后的GET/POST请求发起方法http和https之间没有差异。
为了验证我们的代码是否成功,可以做下JUnit单元测试:
@Test
publicvoiddoTest()throwsClientProtocolException, 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代码
- 有朋友反馈说提供的工具类中没有直接POST JSON对象的方法,下面我提供一下基础方法,供参考(此代码未包含在下文的共享资源中,请自行补充进去)
/**
* 基本Post请求
* @param url 请求url
* @param queryParams 请求头的查询参数
* @param json 直接放入post请求体中的文本(请使用JSON)
* @return
* @throws URISyntaxException
* @throws UnsupportedEncodingException
*/
publicHttpResponse doPostBasic(String url, Map queryParams, String json)throwsURISyntaxException, ClientProtocolException, IOException{
HttpPost pm =newHttpPost();
URIBuilder builder =newURIBuilder(url);
//填入查询参数
if(MapUtils.isNotEmpty(queryParams)){
builder.setParameters(HttpUtil.paramsConverter(queryParams));
}
pm.setURI(builder.build());
//填入post json数据
if(StringUtils.isNotBlank(json)){
//下面的ContentType完整类名为:org.apache.http.entity.ContentType
pm.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
}
return client.execute(pm);
}
- 下面再列举一个传入指定秘钥的https访问方法
public void initSSLConfigForTwoWay() throws Exception {
HttpClientBuilder b = HttpClientBuilder.create();
// 1 Import your own certificate
// String demo_base_Path = System.getProperty("user.dir");
// String demo_base_Path = getClass().getClassLoader().getResource("").getPath();
// String selfcertpath = demo_base_Path + Constant.SELFCERTPATH;
// String trustcapath = demo_base_Path + Constant.TRUSTCAPATH;
// String selfcertpath = demo_base_Path + Constant.SELFCERTPATH;
// String trustcapath = demo_base_Path + Constant.TRUSTCAPATH;
KeyStore selfCert = KeyStore.getInstance("pkcs12");
selfCert.load(getClass().getClassLoader().getResourceAsStream(NbConstant.CERT_FLODER + File.separatorChar + NbConstant.SELFCERTPATH),
NbConstant.SELFCERTPWD.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
kmf.init(selfCert, NbConstant.SELFCERTPWD.toCharArray());
// 2 Import the CA certificate of the server,
KeyStore caCert = KeyStore.getInstance("jks");
caCert.load(getClass().getClassLoader().getResourceAsStream(NbConstant.CERT_FLODER + File.separatorChar + NbConstant.TRUSTCAPATH), NbConstant.TRUSTCAPWD.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
tmf.init(caCert);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
// 3 Set the domain name to not verify
// (Non-commercial IoT platform, no use domain name access generally.)
SSLSocketFactory ssf = new SSLSocketFactory(sc, new String[]{"TLSv1.2", "TLSv1.1", "TLSv1"}, null,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
// If the platform has already applied for a domain name which matches
// the domain name in the certificate information, the certificate
// domain name check can be enabled (open by default)
// SSLSocketFactory ssf = new SSLSocketFactory(sc);
// ClientConnectionManager ccm = this.getConnectionManager();
// SchemeRegistry sr = ccm.getSchemeRegistry();
// sr.register(new Scheme("https", 8743, ssf));
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", ssf)
.build();
// -- allows multi-threaded use
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connMgr.setMaxTotal(200);
connMgr.setDefaultMaxPerRoute(100);
b.setConnectionManager(connMgr);
// finally, build the HttpClient;
// -- done!
// httpClient = new DefaultHttpClient(ccm);
httpClient = b.build();
}
HttpClient实现https调用的更多相关文章
- 用HttpClient发送HTTPS请求报SSLException: Certificate for <域名> doesn't match any of the subject alternative names问题的解决
最近用server酱-PushBear做消息自动推送,用apache HttpClient做https的get请求,但是代码上到服务器端就报javax.net.ssl.SSLException: Ce ...
- Httpclient 支持https(转)
参考:https://jingyan.baidu.com/article/154b46317353d228ca8f4112.html 参考:https://www.jianshu.com/p/a444 ...
- HttpClient远程接口调用-实名认证
1.HttpClient远程接口调用 1)用户注册 注册按钮button提交表单时,要return false form表单 <!-- action="http://localhost ...
- 使用HttpClient发送HTTPS请求以及配置Tomcat支持SSL
这里使用的是HttpComponents-Client-4.1.2 package com.jadyer.util; import java.io.File; import java.io.FileI ...
- android httpClient 支持HTTPS的2种处理方式
摘自: http://www.kankanews.com/ICkengine/archives/9634.shtml 项目中Android https或http请求地址重定向为HTTPS的地址,相信很 ...
- c# 中HttpClient访问Https网站
c# 中HttpClient访问Https网站,加入如下代码: handler = new HttpClientHandler() ;handler.AllowAutoRedirect = true; ...
- httpclient妙用一 httpclient作为客户端调用soap webservice(转)
前面有一篇使用HttpClient调用带参数的post接口方法,这里找到一篇使用HttpClient调用Soap协议接口的方式. 原文地址:httpclient妙用一 httpclient作为客户端调 ...
- 前端https调用后端http
昨晚发生了一个,很........的事 我前端的域名 和后端的域名 都没有做认证,前端的访问的80 调用的后端80 然后我给前端的域名做了认证ssl,但是调用后端的时候报错 原因是 https 调 ...
- https 调用验证失败 peer not authenticated
https 调用验证失败 peer not authenticated 报错日志: Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer ...
- 微信的API都是通过https调用实现的,分为post方法调用和get方法调用。不需要上传数据的采用get方法(使用IntraWeb开发)
首先需要明确的是,微信的API都是通过https调用实现的,分为post方法调用和get方法调用.不需要上传数据的采用get方法(例如获取AccessToken),而需要向微信服务器提交数据的采用po ...
随机推荐
- [转帖] Linux命令拾遗-网络抓包工具
https://www.cnblogs.com/codelogs/p/16060684.html 简介# Linux中有很多抓包工具,如ngrep.tcpdump与tshark等,它们有很多用法与使用 ...
- 【验证码逆向专栏】数美验证码全家桶逆向分析以及 AST 获取动态参数
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容.敏感网址.数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许 ...
- 修改U盘图标
效果如下 方法如下 首先,您需要准备一张您想要设置的图标,它应该是一个512 x 512像素大小的PNG格式图片,其他的也无所谓建议512x512 将U盘插入电脑.确保它已被正确识别并显示在文件资源管 ...
- 使用Lua做为MMOARPG游戏逻辑开发脚本的一点体会
项目背景 目前在一个大型MMOARPG游戏中使用Lua做为逻辑开发语言,Lua占整体代码量的80%. 我们这个MMO游戏开发近2年,客户端8人,项目组总体人数在100人(美术占70%),目前代码量很大 ...
- 21.9 Python 使用Selenium库
Selenium是一个自动化测试框架,主要用于Web应用程序的自动化测试.它可以模拟用户在浏览器中的操作,如打开网页.点击链接.填写表单等,并且可以在代码中实现条件判断.异常处理等功能.Seleniu ...
- C/C++ Npcap包实现数据嗅探
npcap 是Nmap自带的一个数据包处理工具,Nmap底层就是使用这个包进行收发包的,该库,是可以进行二次开发的,不过使用C语言开发费劲,在进行渗透任务时,还是使用Python构建数据包高效,这东西 ...
- Linux系统的一些实用操作 [补档-2023-07-30]
Linux的实用操作 4-1.常用快捷键 强制停止:当某些程序运行时,或者命令输入错误时,可以通过 ctrl + c 来强制结束当前的操作. 退出或登出:当我们要退出某些用户时,或者要退出某些特殊的页 ...
- 递归锁和死锁(Python)
一.递归锁 # Lock :互斥锁 效率高 # RLock :递归(recursion)锁 效率相对低 在同一个线程中可以被acquire多次,如果想要释放锁,acquire多少次就要release多 ...
- 知乎利用 JuiceFS 给 Flink 容器启动加速实践
本文作者胡梦宇,知乎大数据架构开发工程师,主要负责知乎内部大数据组件的二次开发和数据平台建设. 背景 Flink 因为其可靠性和易用性,已经成为当前最流行的流处理框架之一,在流计算领域占据了主导地位. ...
- 数学和CNN里面的卷积和互相关
卷积和互相关 nndl上CNN这章的互相关讲的比较晦涩,简单辨析一下书上的互相关 A.1 数学意义上的卷积就是将卷积核进行翻转之后再进行我们熟悉CNN上的卷积运算 同时互相关就是不将卷积核翻转直接CN ...