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查找当前目录下包含部分内容的文件,并且copy到指定路径的简单方法
1 获取文件列表 find . -name "*.data" |xargs grep -i 'yearvariable' | uniq | awk '{print $1}' |cu ...
- 自动化部署实例(donetcore GitLab CICD )
主要简单的介绍了一下 GitLab CI 的持续集成以及持续部署,这篇将通过 GitLab CI 发布一个 .net core 项目,来带小伙伴们感受一下自动化的魅力,从此告别手动发布. 准备工作 创 ...
- C# 使用字典将枚举转换为String
枚举 public enum ColorType { Red = 10, Blue = 20, Green = 30, Yellow = 40, } String var A1 = "AAA ...
- win11和win10的快捷键列表
win11特有的快捷键 win键就是图案是windows图标的那个按键 作用 快捷键 打开快速设置,win11是展开音量,wifi,蓝牙的设置项,win10也可以用 win + a 打开通知中心和日历 ...
- Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索
Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本.图像等领域,支持文搜.图搜文.图搜图匹配搜索 Similarities 相似度计算.语义匹配搜索工具包,实现 ...
- Volatility 内存数字取证方法
计算机数字取证分为内存取证和磁盘取证,活取证与死取证,不管是那种取证方式,都应尽量避免破环犯罪现场,例如通过内存转储工具对内存进行快照,通过磁盘克隆工具对磁盘进行克隆,方便后期的分析工作,这里将研究内 ...
- Flask 实现简单的图片上传
通过使用Flask框架实现一个简单的图片上传工具,当用户提交图片后会自动将图片保存到upload目录下,代码如下 import os from flask import Flask, request ...
- MakeFile文件的使用 [补档-2023-07-13]
makefile-gdb文件 可以在文件中指定那些文件可以先进行编译,那些文件可以后进行编译,那些文件可以重新编译.他可以自动化编译程序.... 6-1 makefile基本规则 如下: ...
- 使用Fiddler复制并转发http响应数据
1.安装Fiddler 略 2.编辑FiddlerScript,增加拦截判断 Goto OnBeforeResponse,跳转到指定函数,在函数中添加拦截某些http代码,如下. if (oSessi ...
- Firefox浏览器的一些配置
一.在新标签页打开书签 1.打开Firefox浏览器,地址栏输入about:config. 2.选择"接受风险并继续". 3.搜索browser.tabs.loadBookmark ...