springboot2.X集成HttpClient 发送HTTPS 请求
1)jar
<!--httpclient 发送外部https/http 请求-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
2)配置
httpclient:
maxTotal:
defaultMaxPerRoute:
connectTimeout:
connectionRequestTimeout:
socketTimeout:
staleConnectionCheckEnabled: true
# keyStorePath: C:/Users/Administrator/Desktop/广州办映射服务器测试证书20181010/dakehu/keystore.jks #证书路径
keyStorePath: /usr/https_cert/keystore.jks #证书路径
keyStorepass: #证书密码`
3)编写 HttpClient 集成相应的配置
package com.bigcustomer.utils.httpUtil; import lombok.Data;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore; /**
* @author :CX
* @Date :Create in 2018/8/17 9:57
* @Effect :
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "httpclient")
public class HttpClient { private Integer maxTotal; private Integer defaultMaxPerRoute; private Integer connectTimeout; private Integer connectionRequestTimeout; private Integer socketTimeout; private boolean staleConnectionCheckEnabled; //https 证书 路径
private String keyStorePath;
// 证书密码
private String keyStorepass; @Bean(name = "sslcontext")
public SSLContext getSslcontext() {
SSLContext sc = null;
FileInputStream instream = null;
KeyStore trustStore = null;
try {
trustStore = KeyStore.getInstance("JKS");
instream = new FileInputStream(new File(keyStorePath));
trustStore.load(instream, keyStorepass.toCharArray());
// 相信自己的CA和所有自签名的证书
sc = SSLContexts.custom().loadKeyMaterial(trustStore, keyStorepass.toCharArray()).build();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
instream.close();
} catch (IOException e) {
}
}
return sc;
} /**
* 首先实例化一个连接池管理器,设置最大连接数、并发连接数
*
* @return
*/
@Bean(name = "httpClientConnectionManager")
public PoolingHttpClientConnectionManager getHttpClientConnectionManager(@Qualifier("sslcontext") SSLContext sslcontext) {
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslcontext))
.build();
PoolingHttpClientConnectionManager httpClientConnectionManager =
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
//最大连接数
httpClientConnectionManager.setMaxTotal(maxTotal);
//并发数
httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
return httpClientConnectionManager;
} /**
* 实例化连接池,设置连接池管理器。
* 这里需要以参数形式注入上面实例化的连接池管理器
*
* @param httpClientConnectionManager
* @return
*/
@Bean(name = "httpClientBuilder")
public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager) { //HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setConnectionManager(httpClientConnectionManager); return httpClientBuilder;
} /**
* 注入连接池,用于获取httpClient
*
* @param httpClientBuilder
* @return
*/
@Bean
public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder) {
return httpClientBuilder.build();
} /**
* Builder是RequestConfig的一个内部类
* 通过RequestConfig的custom方法来获取到一个Builder对象
* 设置builder的连接信息
* 这里还可以设置proxy,cookieSpec等属性。有需要的话可以在此设置
*
* @return
*/
@Bean(name = "builder")
public RequestConfig.Builder getBuilder() {
RequestConfig.Builder builder = RequestConfig.custom();
return builder.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.setSocketTimeout(socketTimeout)
.setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);
} /**
* 使用builder构建一个RequestConfig对象
*
* @param builder
* @return
*/
@Bean(name = "requestConfig")
public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder) { return builder.build(); } }
4)编写定时回收无效资源的类
package com.bigcustomer.utils.httpUtil; import org.apache.http.conn.HttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; /**
* @author :CX
* @Date :Create in 2018/8/17 10:00
* @Effect : 定时回收没有使用的链接 交还给连接池
*/
@Component
public class IdleConnectionEvictor extends Thread { @Autowired
private HttpClientConnectionManager httpClientConnectionManager;
private volatile boolean shutdown; public IdleConnectionEvictor() {
super();
super.start();
} @Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// 关闭失效的连接
httpClientConnectionManager.closeExpiredConnections();
}
}
} catch (InterruptedException ex) {
// 结束
}
} //关闭清理无效连接的线程
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
5) 工具类
package com.bigcustomer.utils.httpUtil; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.bigcustomer.configs.BaseConfig;
import com.bigcustomer.configs.KeyConfig;
import com.bigcustomer.utils.ExternalHelpUtile;
import com.bigcustomer.utils.SinUtil;
import huashitech.kissucomponent.redis.RedisUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map; /**
* @author :CX
* @Date :Create in 2018/8/17 10:02
* @Effect :
*/
@Component
public class HttpsUtils {
private static Logger logger = LoggerFactory.getLogger(HttpsUtils.class);
static CloseableHttpClient httpClient;
static RequestConfig requestConfig;
static CloseableHttpResponse httpResponse; private static BaseConfig baseConfig;
private static ExternalHelpUtile utile;
private static KeyConfig config;
private static SinUtil sinUtil;
private static RedisUtil redisUtil;
private static String encoding = "utf-8"; @Autowired
public void init(KeyConfig config, BaseConfig baseConfig, RedisUtil redisUtil,
ExternalHelpUtile utile, SinUtil sinUtil,
CloseableHttpClient httpClient
, RequestConfig requestConfig) {
HttpsUtils.config = config;
HttpsUtils.baseConfig = baseConfig;
HttpsUtils.redisUtil = redisUtil;
HttpsUtils.utile = utile;
HttpsUtils.sinUtil = sinUtil;
HttpsUtils.httpClient = httpClient;
HttpsUtils.requestConfig = requestConfig; } //https 封装方法
private static Map<String , Object> baseSendHttpsPost(Map<String, Object> par, String url, String key) throws ClientProtocolException, IOException {
//请求map
LinkedHashMap<String, Object> requestMap = new LinkedHashMap<>();
requestMap.put("mac", null);// 签名会去掉mac
requestMap.put("agentcode", config.getAgentcode());
requestMap.put("msgbody", par); // 签名并对mac 重新赋值
String mac = sinUtil.createMac(requestMap, key);
requestMap.put("mac", mac);
String parStr = JSON.toJSONString(requestMap);
logger.info("参数 :" + parStr);
try { //创建post方式请求对象
HttpPost httpPost = new HttpPost(url); //装填参数
StringEntity stringEntity = null;
if (null != par) {
stringEntity = new StringEntity(parStr,encoding);
httpPost.setEntity(stringEntity);
} logger.info("创建请求httpsPost-URL={},params={}", url, parStr);
//设置header信息
//指定报文头【Content-type】、【User-Agent】
httpPost.setHeader("Content-Type", "application/json;charset="+encoding);
// httpPost.setHeader("Content-Length", params.length() + ""); //执行请求操作,并拿到结果(同步阻塞)
CloseableHttpResponse response = httpClient.execute(httpPost);
//获取结果实体
HttpEntity entity = response.getEntity();
if (entity != null) {
//按指定编码转换结果实体为String类型
String body = EntityUtils.toString(entity, encoding);
logger.info(url + "接口返回报文是:/n" + body);
return JSON.parseObject(body, LinkedHashMap.class , Feature.OrderedField);
}
EntityUtils.consume(entity);
if(response != null ){
//释放链接
response.close();
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (null != httpResponse) {
httpResponse.close();
}
logger.info("请求流关闭完成");
} catch (IOException e) {
e.printStackTrace();
}
}
} }
注意)=========================================================
1.JAVA 使用的证书后缀为JKS , 如果不是需要将证书转换为.jks文件
2.需要在jre中导入证书,而jre(1.8)并不会处理证书链, 必须一个个导入, 如果使用的是中间证书所签发的证书直接导入中间证书即可,
不必导入根(ROOT)证书 , 如果是根证书直接签发的证书 , 则必须导入根证书

springboot2.X集成HttpClient 发送HTTPS 请求的更多相关文章
- 使用HttpClient发送HTTPS请求以及配置Tomcat支持SSL
这里使用的是HttpComponents-Client-4.1.2 package com.jadyer.util; import java.io.File; import java.io.FileI ...
- 通过 Apache Commons HttpClient 发送 HTTPS 请求
1.通过 HTTPS 发送 POST 请求: 2.HTTPS 安全协议采用 TLSv1.2: 3. 使用代理(Proxy)进行 HTTPS 访问: 4.指定 Content-Type 为:applic ...
- 用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 ...
- 【JAVA】通过HttpClient发送HTTP请求的方法
HttpClient介绍 HttpClient 不是一个浏览器.它是一个客户端的 HTTP 通信实现库.HttpClient的目标是发 送和接收HTTP 报文.HttpClient不会去缓存内容,执行 ...
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- (一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
(一)----使用HttpClient发送HTTP请求(通过get方法获取数据) 一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 “超文本传输协议”,是 ...
- .net core使用HttpClient发送代理请求_程序内抓包_Fiddler抓包
前言: 通过Fiddler抓取浏览器请求数据,相信大家已经都会用了,我们知道Fiddler是通过在本机计算器添加一个默认的代理服务器来实现的抓包数据的,端口号为:8888. 其实当我们打开Fiddl ...
- .Net Core 发送https请求/.net core 调用数字证书 使用X509Certificate2
.Net Core 发送https请求 .net core 调用数字证书 使用X509Certificate2 .NET下面的 .netfromwork使用和asp.net core下使用方式不一样 ...
- 简单粗暴套娃模式组json发送https请求
各位童鞋大家好,向来简单粗暴的铁柱兄给大家来玩一手套娃模式来组Json数据,不说别的,无脑套. 当然,这一手比较适合临场用一下,若长期用的话建议搞一套适用的框架,只管set就好了.话不多说开始上课. ...
随机推荐
- C#重写ToString
C# 中的每个类或结构都可隐式继承 <xref:System.Object> 类. 因此,C# 中的每个对象都会获取 <xref:System.Object.ToString%2A& ...
- 15 链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点. p1先走k-1步,p1 p2再一起走 C++: /* struct ListNode { int val; struct ListNode *next; L ...
- 一些你可能需要的okhttp实现
https://blog.csdn.net/qq_17766199/article/details/53186874 今天分享一些我在项目中使用到的okhttp实现,由简至难.(以下内容均在okhtt ...
- Spark(十三)SparkSQL的自定义函数UDF与开窗函数
一 自定义函数UDF 在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_ ...
- day2编写购物商城
作业:购物商城 商品展示,价格 买,加入购物车 付款,钱不够 流程图如下: 代码共有4个文件,如下: 用户文件: alex geng zhang lou zeng 商品文件: 小米3 比亚迪宋 格力变 ...
- umount /dev/shm
[root@test ~]# umount /dev/shm umount: /dev/shm: device is busy. (In some cases useful info a ...
- HTML Input 表单校验之datatype
凡要验证格式的元素均需绑定datatype属性,datatype可选值内置有10类,用来指定不同的验证格式. 如果还不能满足您的验证需求,可以传入自定义datatype,自定义datatype是一个非 ...
- 七牛云整合Ueditor的ThinkPHP版本
首先去七牛云官网下载phpSDK工具放在Think/library/Vendor下. ueditor后台调用方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- 个人博客www.0x002.com
cnblogs只是相当于一个备份,感兴趣的读者赏脸关注下.
- Java工具类之浮点精确计算
public class Arith { // 默认除法运算精度 private static final int DEF_DIV_SCALE = 10; // 构造器私有,让这个类不能实例化 pri ...