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 ...
随机推荐
- 简单定位占用最高CPU的java进程信息
公司里面一个应用不小心点击就会导致系统性能下降很明显. 性能组的同事定位到了, 我这里以学习的态度重现一下这个过程. 1. 问题再现 产品一个非常大数据量的帮助, 点击之后就会占用非常多的cpu 因为 ...
- PG13 离线安装的简单办法
1. 发现上班时间公司的网络几乎不可用 还是得找时间下载好离线包才可以. 找了一个最简单的办法 地址 https://yum.postgresql.org/ 选择版本 这次我选择最新的 继续之后继续选 ...
- 《SAIS Supervising and Augmenting Intermediate Steps for Document-Level Relation Extraction》论文阅读笔记
代码 原文地址 预备知识: 1.什么是标记索引(token indices)? 标记索引是一种用于表示文本中的单词或符号的数字编码.它们可以帮助计算机理解和处理自然语言.例如,假如有一个字典{ ...
- vue/cli的配置详解
查看vue/cli的配置 vue的脚手架隐藏了所有的webpack相关的配置,若是想要查看webpack的配置 你可以去执行 vue inspect > output.js 这样就可以查看它的配 ...
- gRPC with JWT
在 gRPC 中使用 JWT(JSON Web Tokens)进行身份验证是一种常见的做法,它可以帮助你确保请求方的身份和权限.下面是一种使用 gRPC 和 JWT 进行身份验证的步骤: 生成和签发 ...
- 微信小程序-页面跳转Tabbar
官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar 首先我们 ...
- UIE_Slim满足工业应用场景,解决推理部署耗时问题,提升效能。
项目链接:fork一下即可 UIE Slim满足工业应用场景,解决推理部署耗时问题,提升效能! 如果有图片缺失查看原项目 UIE Slim满足工业应用场景,解决推理部署耗时问题,提升效能 在UIE强大 ...
- 在Golang中实现多态
目录 1.说明 2.多态 3.代码示例 4.总结 1.说明 和流行的面向对象语言不同,go 中没有面向对象的说法,也没有对应的封装.继承和多态,也许 go 的设计就不是和OOP对齐,想使用OOP,那就 ...
- 基于.NET三维控件的个性化管道软件开发
1 简介 管道广泛用于化工.工厂.建筑.市政等方面,关系到国计民生.虽然管道设计软件种类繁多,有的也非常强大(然而也非常昂贵),但也并不能完全满足个性化需要. 如何快速开发一款满足自己需求的三维管道设 ...
- 盘点下4个Winform UI开源控件库
今天一起来盘点下4个Winform UI开源控件库,有.Net Framework,也有.Net Core. 1.支持.Net 7的开源UI组件框架 项目简介 这是一个基于.Net Framework ...