package com.cmcc.ac.health.pay.util.http;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
/**
* HTTP工具类,基于HttpComponent
*
* @Author Grant
* @Date 2021/4/25 8:34
**/
public class HttpUtil {
private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
private static PoolingHttpClientConnectionManager connectionManager;
private static RequestConfig requestConfig;
private static HttpUtil newHttpUtil = new HttpUtil();
private static IdleConnectionMonitorThread ict;
/**
* 单例模式
*/
private HttpUtil() {
connectionManager = new PoolingHttpClientConnectionManager();
/* 默认最大连接数为200 */
int defaultMaxTotal = 3000;
connectionManager.setMaxTotal(defaultMaxTotal);
/* 每个路由默认连接数为20 */
int defaultMaxPerRoute = 400;
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
/* 默认从连接池获取连接的超时时间2秒 */
int defaultConnectRequestTimeOut = 5 * 1000;
/* 默认传输超时时间为10秒 */
int defaultSocketTimeOut = 10 * 1000;
/*默认连接超时时间10秒*/
int defaultConnectTimeOut = 10 * 1000;
requestConfig = RequestConfig.custom().setSocketTimeout(defaultSocketTimeOut)
.setConnectionRequestTimeout(defaultConnectRequestTimeOut)
.setConnectTimeout(defaultConnectTimeOut).build();
ict = new IdleConnectionMonitorThread(connectionManager);
/* 每隔5分钟清空一次失效链接 */
int defalutClearTime = 5000;
ict.setClearTime(defalutClearTime);
ict.start();
}
public static HttpUtil getInstance() {
return newHttpUtil;
}
public static void destroy() {
ict.shutdown();
}
public String sendPostByMap(String url, Map<String, String> map) {
return sendPostByMap(url, map, null);
}
public String sendPostByMap(String url, Map<String, String> map, String revCharset) {
List<NameValuePair> list = new ArrayList<>();
if (map != null && map.size() > 0) {
for (Entry<String, String> entry : map.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
return sendByNameValuePairs(url, list, revCharset);
}
public String sendByJson(String url, String json) {
return sendHttpPost(url, new StringEntity(json, ContentType.create("application/json",
Consts.UTF_8)), "utf-8");
}
public String sendByJson(String url, String json, String charset) {
return sendHttpPost(url, new StringEntity(json, ContentType.create("application/json",
charset)), charset);
}
public String sendPostByString(String url, String str, ContentType contentType, String charType) {
return sendHttpPost(url, new StringEntity(str, contentType), charType);
}
public String sendByNameValuePairs(String url, List<NameValuePair> nvps) {
return sendByNameValuePairs(url, nvps, null);
}
public String sendByNameValuePairs(String url, List<NameValuePair> nvps, String revCharset) {
return sendHttpPost(url, new UrlEncodedFormEntity(nvps, Consts.UTF_8), revCharset);
}
public String sendByXmlPost(String url, String xml) {
return sendHttpPost(url, new StringEntity(xml, ContentType.create("application/xml", "GBK")), "GBK");
}
public String sendByIcbcXmlPost(String url, String xml) {
return sendHttpPost(url, new StringEntity(xml, ContentType.create("INFOSEC_SIGN/1.0", "ISO8859-1")), "GBK");
}
/**
* 发送http的post请求
*
* @return java.lang.String
* @Author Grant
* @Date 8:51 2021/4/25
* @Param [url, entity 请求参数编码格式, revCharset 接收参数编码格式]
**/
private String sendHttpPost(String url, HttpEntity entity, String revCharset) {
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
httpPost.setEntity(entity);
StringBuffer result = new StringBuffer();
BufferedReader buffer = null;
InputStreamReader isr = null;
String line;
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) {
InputStream input = response.getEntity().getContent();
if (revCharset == null) {
isr = new InputStreamReader(input);
} else {
isr = new InputStreamReader(input, revCharset);
}
buffer = new BufferedReader(isr, 10 * 1024);
result = new StringBuffer();
while ((line = buffer.readLine()) != null) {
result.append(line);
result.append(System.getProperty("line.separator"));
}
if (result.lastIndexOf(System.getProperty("line.separator")) != -1) {
result.delete(result.lastIndexOf(System.getProperty("line.separator")),
result.length());
}
} else {
logger.error("Http请求返回码错误:" + code);
}
} catch (ClientProtocolException e) {
logger.error("Http请求错误:", e);
} catch (IOException e) {
logger.error("IO错误:", e);
} finally {
try {
if (response != null) {
response.close();
}
if (buffer != null) {
buffer.close();
}
if (isr != null) {
isr.close();
}
} catch (IOException e) {
logger.error("IO错误:", e);
}
}
return result.toString();
}
/**
* 发送http的get请求
*
* @return java.lang.String
* @Author Grant
* @Date 8:52 2021/4/25
* @Param [url]
**/
public String sendHttpGet(String url) {
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig);
StringBuffer result = new StringBuffer();
BufferedReader buffer = null;
InputStreamReader isr = null;
String line;
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) {
InputStream input = response.getEntity().getContent();
isr = new InputStreamReader(input);
buffer = new BufferedReader(isr, 10 * 1024);
result = new StringBuffer();
while ((line = buffer.readLine()) != null) {
result.append(line);
result.append(System.getProperty("line.separator"));
}
if (result.lastIndexOf(System.getProperty("line.separator")) != -1) {
result.delete(result.lastIndexOf(System.getProperty("line.separator")),
result.length());
}
} else {
logger.error("Http请求返回码错误:" + code);
}
} catch (ClientProtocolException e) {
logger.error("Http请求错误:", e);
} catch (IOException e) {
logger.error("IO错误:", e);
} finally {
try {
if (response != null) {
response.close();
}
if (buffer != null) {
buffer.close();
}
if (isr != null) {
isr.close();
}
} catch (IOException e) {
logger.error("IO错误:", e);
}
}
return result.toString();
}
/**
* 该线程负责清理失效连接和空闲过长连接
*
* @Author Grant
* @Date 8:46 2021/4/25
* @Param
* @return
**/
private static class IdleConnectionMonitorThread extends Thread {
private final HttpClientConnectionManager connMgr;
private volatile boolean shutdown;
private int clearTime = 5000;
public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
super();
this.connMgr = connMgr;
}
public void setClearTime(int clearTime) {
this.clearTime = clearTime;
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(clearTime);
// 关闭失效连接
connMgr.closeExpiredConnections();
// 关闭空闲超过30秒的连接
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ex) {
logger.error("异常:", ex);
}
}
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
}