org.apache.httpcomponents
httpasyncclient
4.1
# http配置服务
http:
# 最大连接数
maxTotal: 100
# 并发数
defaultMaxPerRoute : 20
# 创建连接的最长时间
connectTimeout: 1000
# 从连接池中获取到连接的最长时间
connectionRequestTimeout: 500
# 数据传输的最长时间
socketTimeout: 10000
# 提交请求前测试连接是否可用
staleConnectionCheckEnabled: true
/**
* @program: springboot-mybatis-swagger
* @description: http请求
* @author: Mario
* @create: 2019-07-15 09:06
**/
@Configuration
public class HttpClientConfig {
@Value("${http.maxTotal}")
private Integer maxTotal;
@Value("${http.defaultMaxPerRoute}")
private Integer defaultMaxPerRoute;
@Value("${http.connectTimeout}")
private Integer connectTimeout;
@Value("${http.connectionRequestTimeout}")
private Integer connectionRequestTimeout;
@Value("${http.socketTimeout}")
private Integer socketTimeout;
@Value("${http.staleConnectionCheckEnabled}")
private boolean staleConnectionCheckEnabled;
/**
* 首先实例化一个连接池管理器,设置最大连接数、并发连接数
* @return
*/
@Bean(name = "httpClientConnectionManager")
public PoolingHttpClientConnectionManager getHttpClientConnectionManager(){
PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
//最大连接数
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
public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder){
return builder.build();
}
}
/**
* @program: springboot-mybatis-swagger
* @description: http启动与关闭
* @author: Mario
* @create: 2019-07-15 09:09
**/
@Component
public class IdleConnectionEvictor extends Thread {
@Autowired
private HttpClientConnectionManager connMgr;
private volatile boolean shutdown;
public IdleConnectionEvictor() {
super();
super.start();
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// 关闭失效的连接
connMgr.closeExpiredConnections();
}
}
} catch (InterruptedException ex) {
// 结束
}
}
//关闭清理无效连接的线程
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
/**
* @program: springboot-mybatis-swagger
* @description: HTTP请求结果
* @author: Mario
* @create: 2019-07-15 09:10
**/
@Data
public class HttpResultDTO {
// 响应码
@NonNull
private Integer code;
// 响应体
@NonNull
private String body;
}
Get/Post等请求可能封装了多余参数,后续可以自行拆解
@Component
public class HttpAPIController {
private static CloseableHttpClient httpClient;
/**
* 信任SSL证书
*/
static {
try {
SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL)
.loadTrustMaterial((x, y) -> true).build();
/**
* 一、连接超时:connectionTimeout-->指的是连接一个url的连接等待时间
* 二、读取数据超时:SocketTimeout-->指的是连接上一个url,获取response的返回等待时间
*/
RequestConfig config = RequestConfig.custom().setConnectTimeout(500000).setSocketTimeout(500000).build();
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext)
.setSSLHostnameVerifier((x, y) -> true).build();
} catch (Exception e) {
e.printStackTrace();
}
}
@Autowired
private RequestConfig config;
/**
* @description GET---不含参
* @param url
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:02
*/
/*public HttpResultDTO doGet(String url) throws Exception {
// 声明 http get 请求
HttpGet httpGet = new HttpGet(url);
// 装载配置信息
httpGet.setConfig(config);
// 允许重定向
httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpGet);
// 返回响应代码与内容
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}*/
/**
* @description GET---含请求头
* @param url
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:04
*/
/* public HttpResultDTO doGetWithHeaders(String url, Map headers) throws Exception {
// 声明 http get 请求
HttpGet httpGet = new HttpGet(url);
// 装载配置信息
httpGet.setConfig(config);
// 设置请求头
if (headers != null) {
for (String key : headers.keySet()) {
String value = headers.get(key).toString();
httpGet.addHeader(key,value);
}
}
// 允许重定向
httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpGet);
// 返回响应代码与内容
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}*/
/**
* @description GET---含Map请求参数
* @param url
* @param mapParams
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:06
*/
/*public HttpResultDTO doGetWithParams(String url, Map mapParams) throws Exception {
// 包装URL
URIBuilder uriBuilder = new URIBuilder(url);
if (mapParams != null) {
// 遍历map,拼接请求参数
for (Map.Entry entry : mapParams.entrySet()) {
uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
}
}
// 调用不带参数的get请求
return this.doGet(uriBuilder.build().toString());
}*/
/**
* @description GET---含Map请求参数且含请求头
* @param url
* @param mapParams
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:08
*/
public HttpResultDTO doGetWithParamsAndHeaders(String url, Map mapParams , Map headers) throws Exception {
// 声明 http get 请求
HttpGet httpGet = new HttpGet(url);
// 装载配置信息
httpGet.setConfig(config);
// 允许重定向
httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
// 包装请求行
if (mapParams != null) {
// 包装URL
URIBuilder uriBuilder = new URIBuilder(url);
// 遍历map,拼接请求参数
for (Map.Entry entry : mapParams.entrySet()) {
uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
}
// 新的请求行
url = uriBuilder.build().toString();
}
// 设置请求头
if (headers != null) {
for (String key : headers.keySet()) {
String value = headers.get(key).toString();
httpGet.addHeader(key,value);
}
}
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpGet);
// 返回响应代码与内容
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}
/**
* @description POST--不含参
* @param url
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:14
*/
/*public HttpResultDTO doPost(String url) throws Exception {
// 声明httpPost请求
HttpPost httpPost = new HttpPost(url);
// 加入配置信息
httpPost.setConfig(config);
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpPost);
// 返回响应代码与内容
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}*/
/**
* @description POST---含参
* @param url
* @param params
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:16
*/
/*public HttpResultDTO doPostWithParams(String url, Map params) throws Exception {
// 声明httpPost请求
HttpPost httpPost = new HttpPost(url);
// 加入配置信息
httpPost.setConfig(config);
// 判断map是否为空,不为空则进行遍历,封装from表单对象
if (params != null) {
List list = new ArrayList();
for (Map.Entry entry : params.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
}
// 构造from表单对象
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");
// 把表单放到post里
httpPost.setEntity(urlEncodedFormEntity);
}
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpPost);
// 返回响应代码与内容
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}*/
/**
* @description POST---含请求头
* @param url
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:17
*/
/*public HttpResultDTO doPostWithHeaders(String url, Map headers) throws Exception {
// 声明httpPost请求
HttpPost httpPost = new HttpPost(url);
// 加入配置信息
httpPost.setConfig(config);
// 设置请求头
if (headers != null) {
for (String key : headers.keySet()) {
String value = headers.get(key).toString();
httpPost.addHeader(key,value);
}
}
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpPost);
// 返回响应代码与内容
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}*/
/**
* @description POST---含参(请求路径、Map参数、请求头)
* @param url
* @param mapParams
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:22
*/
public HttpResultDTO doPostWithParamsAndHeaders(String url, Map mapParams , Map headers) throws Exception {
// 声明httpPost请求
HttpPost httpPost = new HttpPost(url);
// 加入配置信息
httpPost.setConfig(config);
// 判断map是否为空,不为空则进行遍历,封装from表单对象
if (mapParams != null) {
List list = new ArrayList();
for (Map.Entry entry : mapParams.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
}
// 构造from表单对象
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");
// 把表单放到post里
httpPost.setEntity(urlEncodedFormEntity);
}
// 设置请求头
if (headers != null) {
for (String key : headers.keySet()) {
String value = headers.get(key).toString();
httpPost.addHeader(key,value);
}
}
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpPost);
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}
/**
* @description POST---含参(请求路径、JSON参数串、请求头)
* @param url
* @param jsonParam
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:20
*/
public static HttpResultDTO doPostWithJsonParamAndHeaders(String url, String jsonParam, Map headers) throws Exception {
// 声明httpPost请求
HttpPost httpPost = new HttpPost(url);
// 设置请求头
if (headers != null) {
for (String key : headers.keySet()) {
String value = headers.get(key).toString();
httpPost.addHeader(key, value);
}
}
// 设置以Json数据方式发送
StringEntity stringEntity = new StringEntity(jsonParam, "utf-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
// 发起请求
CloseableHttpResponse response = httpClient.execute(httpPost);
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}
/**
* @description PUT---含参(请求路径、JSON参数串、请求头)
* @param url
* @param jsonParam
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:32
*/
public static HttpResultDTO doPutWithJsonAndHeaders(String url,String jsonParam,Map headers) throws Exception{
// 声明httpPut请求
HttpPut httpPut = new HttpPut(url);
//设置header
httpPut.setHeader("Content-type", "application/json");
if (headers != null && headers.size() > 0) {
for (Map.Entry entry : headers.entrySet()) {
httpPut.setHeader(entry.getKey(),entry.getValue());
}
}
//组织请求参数
if (StringUtils.isNotEmpty(jsonParam)) {
StringEntity stringEntity = new StringEntity(jsonParam, "utf-8");
httpPut.setEntity(stringEntity);
}
// 发起请求
CloseableHttpResponse response = httpClient.execute(httpPut);
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}
/**
* @description DELETE---含参(请求路径、请求头)
* @param url
* @param headers
* @return com.mark.dc2.DTO.HttpResultDTO
* @author Mario
* @date 2019/7/23 9:37
*/
public static HttpResultDTO doDeleteWithHeaders(String url,Map headers) throws Exception{
// 声明httpDelete请求
HttpDelete httpDelete = new HttpDelete(url);
//设置header
if (headers != null && headers.size() > 0) {
for (Map.Entry entry : headers.entrySet()) {
httpDelete.setHeader(entry.getKey(),entry.getValue());
}
}
// 发起请求
CloseableHttpResponse response = httpClient.execute(httpDelete);
return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), "UTF-8"));
}
}