第一种写法:

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import javax.activation.MimetypesFileTypeMap;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException; import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
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.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils; import lombok.extern.slf4j.Slf4j;
import net.dreamlu.common.entity.DownLoadFile;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.PropertyFilter; @Slf4j
public class HttpclientUtils implements IDictConst {
private final static int CONNECT_TIMEOUT = 4000; // 连接超时毫秒
private final static int SOCKET_TIMEOUT = 30000; // 传输超时毫秒
private final static int REQUESTCONNECT_TIMEOUT = 3000; // 获取请求超时毫秒
private final static String ENCODE_CHARSET = "utf-8"; // 响应报文解码字符集 static class RetryHandler implements HttpRequestRetryHandler {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 3) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
} }; public static CloseableHttpClient createSSLClientDefault(HttpHost proxy) {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
HttpRequestRetryHandler retryHandler = new RetryHandler();
Builder buider = RequestConfig.custom().setConnectionRequestTimeout(REQUESTCONNECT_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT);
if (null != proxy) {
buider.setProxy(proxy);
}
RequestConfig requestConfig = buider.build();
HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfig).setRetryHandler(retryHandler).build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
log.error(e.getMessage(), e);
}
return HttpClients.createDefault();
} public static String buildMap(Map<String, Object> map) {
StringBuffer sb = new StringBuffer();
if (map != null && map.size() > 0) {
for (String key : map.keySet()) {
sb.append(key + "=");
if (null == map.get(key)) {
sb.append("&");
} else {
String value = String.valueOf(map.get(key));
try {
value = URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
}
sb.append(value + "&");
}
}
}
return sb.toString();
} /**
* 发送HTTP_GET请求
*
* @see 1)该方法会自动关闭连接,释放资源
* @see 2)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
* @see 3)请求参数含中文时,经测试可直接传入中文,HttpClient会自动编码发给Server,应用时应根据实际效果决 定传入前是否转码
* @see 4)该方法会自动获取到响应消息头中[Content-Type:text/html; charset=GBK]的charset值作为响应报文的 解码字符集
* @see 5)若响应消息头中无Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1作为响应报文的解码字符 集
* @param reqURL 请求地址(含参数)
* @return 远程主机响应正文 HttpHost proxy = new HttpHost("192.168.15.4", 3128);
*/
public static JSONObject sendGetRequest(String reqURL, Map<String, Object> map, HttpHost proxy) {
String param = buildMap(map);
if (null != param) {
reqURL += "?" + param;
}
JSONObject respContent = new JSONObject(); // 响应内容
// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
HttpGet httpget = new HttpGet(reqURL);
httpget.setHeader("Connection", "close");
CloseableHttpResponse response = null;
try {
response = createSSLClientDefault(proxy).execute(httpget, HttpClientContext.create()); // 执行GET请求
HttpEntity entity = response.getEntity(); // 获取响应实体
if (null != entity) {
Charset respCharset = Charset.forName(ENCODE_CHARSET);
respContent = JSONObject.fromObject(EntityUtils.toString(entity, respCharset), getJsonConfig());
log.info("发送get请求返回结果:{}", respContent);
EntityUtils.consume(entity);
} else {
log.error("发送get请求返回错误:{}", response);
}
} catch (ConnectTimeoutException cte) {
log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
respContent.put(CODE, -1000);
respContent.put(MSG, cte.getMessage());
} catch (SocketTimeoutException ste) {
log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
respContent.put(CODE, -1000);
respContent.put(MSG, ste.getMessage());
} catch (ClientProtocolException cpe) {
log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
respContent.put(CODE, -1000);
respContent.put(MSG, cpe.getMessage());
} catch (ParseException pe) {
log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
respContent.put(CODE, -1000);
respContent.put(MSG, pe.getMessage());
} catch (IOException ioe) {
log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
respContent.put(CODE, -1000);
respContent.put(MSG, ioe.getMessage());
} catch (Exception e) {
log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
respContent.put(CODE, -1000);
respContent.put(MSG, e.getMessage());
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
if (httpget != null) {
httpget.releaseConnection();
}
}
return respContent;
} /**
* 将null值的字段去掉
*
* @return
*/
private static JsonConfig getJsonConfig() {
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
@Override
public boolean apply(Object arg0, String arg1, Object arg2) {
return StringUtils.equals("null", String.valueOf(arg2));
}
});
return jsonConfig;
} /**
* 发送HTTP_POST请求 type: 默认是表单请求,
*
* @see 1)该方法允许自定义任何格式和内容的HTTP请求报文体
* @see 2)该方法会自动关闭连接,释放资源
* @see 3)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
* @see 4)请求参数含中文等特殊字符时,可直接传入本方法,并指明其编码字符集encodeCharset参数,方法内部会自 动对其转码
* @see 5)该方法在解码响应报文时所采用的编码,取自响应消息头中的[Content-Type:text/html; charset=GBK]的 charset值
* @see 6)若响应消息头中未指定Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1
* @param reqURL 请求地址
* @param param 请求参数,若有多个参数则应拼接为param11=value11&22=value22&33=value33的形式
* @param type 编码字符集,编码请求数据时用之,此参数为必填项(不能为""或null)
* @return 远程主机响应正文
*/
public static JSONObject sendPostRequest(String reqURL, Map<String, Object> map, String type, HttpHost proxy) {
JSONObject respContent = new JSONObject();
// 设置请求和传输超时时间
HttpPost httpPost = new HttpPost(reqURL);
httpPost.setHeader("Connection", "close");
// 这就有可能会导致服务端接收不到POST过去的参数,比如运行在Tomcat6.0.36中的Servlet,所以我们手工指定CONTENT_TYPE头消息
if (type != null && type.length() > 0) {
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=" + ENCODE_CHARSET);
} else {
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=" + ENCODE_CHARSET);
}
CloseableHttpResponse response = null;
try {
// 判断map不为空
if (map != null) {
// 声明存放参数的List集合
List<NameValuePair> params = new ArrayList<NameValuePair>();
// 遍历map,设置参数到list中
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (null != entry.getValue()) {
params.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
}
}
// 创建form表单对象
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, ENCODE_CHARSET);
formEntity.setContentType("Content-Type:application/json");
// 把表单对象设置到httpPost中
httpPost.setEntity(formEntity);
}
// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
HttpEntity entity = response.getEntity();
if (null != entity) {
respContent = JSONObject.fromObject(EntityUtils.toString(entity, Charset.forName(ENCODE_CHARSET)), getJsonConfig());
log.info("发送post请求返回结果:{}", respContent);
EntityUtils.consume(entity);
} else {
log.error("发送post请求返回错误:{}", response);
}
} catch (ConnectTimeoutException cte) {
log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
respContent.put(CODE, -1000);
respContent.put(MSG, cte.getMessage());
} catch (SocketTimeoutException ste) {
log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
respContent.put(CODE, -1000);
respContent.put(MSG, ste.getMessage());
} catch (ClientProtocolException cpe) {
log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
respContent.put(CODE, -1000);
respContent.put(MSG, cpe.getMessage());
} catch (ParseException pe) {
log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
respContent.put(CODE, -1000);
respContent.put(MSG, pe.getMessage());
} catch (IOException ioe) {
log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
respContent.put(CODE, -1000);
respContent.put(MSG, ioe.getMessage());
} catch (Exception e) {
log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
respContent.put(CODE, -1000);
respContent.put(MSG, e.getMessage());
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
if (httpPost != null) {
httpPost.releaseConnection();
}
}
return respContent;
} public static String getContentType(String filename) {
String contentType = null;
try {
contentType = new MimetypesFileTypeMap().getContentType(filename);
} catch (Exception e) {
e.printStackTrace();
}
return contentType;
} /**
* 上传文件功能
*
* @param reqURL
* @param b
* @param filename
* @param map
* @param type
* @return
*/
public static JSONObject sendPostFileRequest(String reqURL, byte[] b, String filename, Map<String, Object> map, HttpHost proxy) {
JSONObject respContent = new JSONObject();
HttpPost httpPost = new HttpPost(reqURL);
httpPost.setHeader("Connection", "close");
CloseableHttpResponse response = null;
try {
// 判断map不为空
if (map != null) {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setCharset(Charset.forName(ENCODE_CHARSET));
multipartEntityBuilder.addBinaryBody("file", b, ContentType.create(getContentType(filename)), filename);
for (Map.Entry<String, Object> entry : map.entrySet()) {
multipartEntityBuilder.addTextBody(entry.getKey(), String.valueOf(entry.getValue()));
}
HttpEntity httpEntity = multipartEntityBuilder.build();
httpPost.setEntity(httpEntity);
}
// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
HttpEntity entity = response.getEntity();
if (null != entity) {
respContent = JSONObject.fromObject(EntityUtils.toString(entity, Charset.forName(ENCODE_CHARSET)), getJsonConfig());
log.info("发送post请求返回结果:{}", respContent);
EntityUtils.consume(entity);
} else {
log.error("发送post请求返回错误:{}", response);
}
} catch (ConnectTimeoutException cte) {
log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
respContent.put(CODE, -1000);
respContent.put(MSG, cte.getMessage());
} catch (SocketTimeoutException ste) {
log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
respContent.put(CODE, -1000);
respContent.put(MSG, ste.getMessage());
} catch (ClientProtocolException cpe) {
log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
respContent.put(CODE, -1000);
respContent.put(MSG, cpe.getMessage());
} catch (ParseException pe) {
log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
respContent.put(CODE, -1000);
respContent.put(MSG, pe.getMessage());
} catch (IOException ioe) {
log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
respContent.put(CODE, -1000);
respContent.put(MSG, ioe.getMessage());
} catch (Exception e) {
log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
respContent.put(CODE, -1000);
respContent.put(MSG, e.getMessage());
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
if (httpPost != null) {
httpPost.releaseConnection();
}
}
return respContent;
} /**
* 上传文件功能
*
* @param reqURL
* @param b
* @param filename
* @param map
* @param type
* @return
*/
public static DownLoadFile downFileRequest(String reqURL, Map<String, Object> map, HttpHost proxy) {
DownLoadFile respContent = new DownLoadFile();
HttpPost httpPost = new HttpPost(reqURL);
httpPost.setHeader("Connection", "close");
CloseableHttpResponse response = null;
try {
// 判断map不为空
if (map != null) {
// 声明存放参数的List集合
List<NameValuePair> params = new ArrayList<NameValuePair>();
// 遍历map,设置参数到list中
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (null != entry.getValue()) {
params.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
}
}
// 创建form表单对象
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, ENCODE_CHARSET);
formEntity.setContentType("Content-Type:application/json");
// 把表单对象设置到httpPost中
httpPost.setEntity(formEntity);
}
// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
int code = response.getStatusLine().getStatusCode();
if (code == 302) {
Header header = response.getFirstHeader("location"); // 跳转的目标地址是在 HTTP-HEAD上
String newuri = header.getValue(); // 这就是跳转后的地址,再向这个地址发出新申请
httpPost = new HttpPost(newuri);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
code = response.getStatusLine().getStatusCode();
if (code == 200) {
respContent.setFileName(StringUtils.substringAfterLast(newuri, "/"));
HttpEntity entity = response.getEntity();
if (null != entity) {
respContent.setFileContent(EntityUtils.toByteArray(entity));
EntityUtils.consume(entity);
} else {
log.error("发送post请求返回错误:{}", response);
}
}
} else if (code == 200) {
Header header = response.getFirstHeader("location"); // 跳转的目标地址是在 HTTP-HEAD上
String newuri = header.getValue();
HttpEntity entity = response.getEntity();
if (null != entity) {
respContent.setFileName(StringUtils.substringAfterLast(newuri, "/"));
respContent.setFileContent(EntityUtils.toByteArray(entity));
EntityUtils.consume(entity);
} else {
log.error("发送post请求返回错误:{}", response);
}
}
} catch (ConnectTimeoutException cte) {
log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
} catch (SocketTimeoutException ste) {
log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
} catch (ClientProtocolException cpe) {
log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
} catch (ParseException pe) {
log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
} catch (IOException ioe) {
log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
} catch (Exception e) {
log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
if (httpPost != null) {
httpPost.releaseConnection();
}
}
return respContent;
}
}

第二种写法;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
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.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
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.pool.PoolStats;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.sinoeyes.common.IDictConst;
import com.sinoeyes.web.entity.achieve.DownLoadFile; import net.sf.json.JSONObject; public class HttpClientUtil implements IDictConst {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
private final static int CONNECT_TIMEOUT = 4000; // 连接超时毫秒
private final static int SOCKET_TIMEOUT = 30000; // 传输超时毫秒
private final static int SOCKET_TIMEOUT_DELAY = 180000; // 最长传输超时毫秒
private final static int REQUESTCONNECT_TIMEOUT = 3000; // 获取请求超时毫秒
private final static int CONNECT_TOTAL = 800; // 最大连接数
private final static int CONNECT_ROUTE = 800; // 每个路由基础的连接数
private final static String ENCODE_CHARSET = "utf-8"; // 响应报文解码字符集
private final static String RESP_CONTENT = "通信失败";
public static PoolingHttpClientConnectionManager connManager = null;
private static CloseableHttpClient httpClient = null;
static {
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslsf = createSSLConnSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", plainsf).register("https", sslsf).build();
connManager = new PoolingHttpClientConnectionManager(registry);
// 将最大连接数增加到200
connManager.setMaxTotal(CONNECT_TOTAL);
// 将每个路由基础的连接增加到20
connManager.setDefaultMaxPerRoute(CONNECT_ROUTE);
// 可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
connManager.setValidateAfterInactivity(30000);
// 设置socket超时时间
SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(SOCKET_TIMEOUT).build();
connManager.setDefaultSocketConfig(socketConfig); RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(REQUESTCONNECT_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT)
.build();
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 3) {// 如果已经重试了3次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {// 超时
return true;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
return false;
}
if (exception instanceof SSLException) {// ssl握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
};
httpClient = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(requestConfig).setRetryHandler(httpRequestRetryHandler).build();
if (connManager != null && connManager.getTotalStats() != null) {
logger.info("now client pool " + connManager.getTotalStats().toString());
}
} /**
* 发送HTTP_GET请求
*
* @see 1)该方法会自动关闭连接,释放资源
* @see 2)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
* @see 3)请求参数含中文时,经测试可直接传入中文,HttpClient会自动编码发给Server,应用时应根据实际效果决 定传入前是否转码
* @see 4)该方法会自动获取到响应消息头中[Content-Type:text/html; charset=GBK]的charset值作为响应报文的 解码字符集
* @see 5)若响应消息头中无Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1作为响应报文的解码字符 集
* @param reqURL 请求地址(含参数)
* @return 远程主机响应正文
*/
public static String sendGetRequest(String reqURL, String param) {
if (null != param) {
reqURL += "?" + param;
}
String respContent = RESP_CONTENT; // 响应内容
// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
HttpGet httpget = new HttpGet(reqURL);
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpget, HttpClientContext.create()); // 执行GET请求
HttpEntity entity = response.getEntity(); // 获取响应实体
if (null != entity) {
Charset respCharset = ContentType.getOrDefault(entity).getCharset();
respContent = EntityUtils.toString(entity, respCharset);
EntityUtils.consume(entity);
}
} catch (ConnectTimeoutException cte) {
logger.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
} catch (SocketTimeoutException ste) {
logger.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
} catch (ClientProtocolException cpe) {
// 该异常通常是协议错误导致:比如构造HttpGet对象时传入协议不对(将'http'写成'htp')or响应内容不符合HTTP协议要求等
logger.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
} catch (ParseException pe) {
logger.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
} catch (IOException ioe) {
// 该异常通常是网络原因引起的,如HTTP服务器未启动等
logger.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
} catch (Exception e) {
logger.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
if (httpget != null) {
httpget.releaseConnection();
}
}
return respContent;
} public static String sendPostRequest(String reqURL, String param) throws IOException {
return sendPostRequest(reqURL, param, "");
} /**
* 发送HTTP_POST请求 type: 默认是表单请求,
*
* @see 1)该方法允许自定义任何格式和内容的HTTP请求报文体
* @see 2)该方法会自动关闭连接,释放资源
* @see 3)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
* @see 4)请求参数含中文等特殊字符时,可直接传入本方法,并指明其编码字符集encodeCharset参数,方法内部会自 动对其转码
* @see 5)该方法在解码响应报文时所采用的编码,取自响应消息头中的[Content-Type:text/html; charset=GBK]的 charset值
* @see 6)若响应消息头中未指定Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1
* @param reqURL 请求地址
* @param param 请求参数,若有多个参数则应拼接为param11=value11&22=value22&33=value33的形式
* @param type 编码字符集,编码请求数据时用之,此参数为必填项(不能为""或null)
* @return 远程主机响应正文
*/
public static String sendPostRequest(String reqURL, String param, String type) {
String result = RESP_CONTENT;
// 设置请求和传输超时时间
HttpPost httpPost = new HttpPost(reqURL);
// 这就有可能会导致服务端接收不到POST过去的参数,比如运行在Tomcat6.0.36中的Servlet,所以我们手工指定CONTENT_TYPE头消息
if (type != null && type.length() > 0) {
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=" + ENCODE_CHARSET);
} else {
httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=" + ENCODE_CHARSET);
}
CloseableHttpResponse response = null;
try {
if (param != null) {
StringEntity entity = new StringEntity(param, ENCODE_CHARSET);
httpPost.setEntity(entity);
}
logger.info("开始执行请求:" + reqURL);
// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
response = httpClient.execute(httpPost, HttpClientContext.create());
HttpEntity entity = response.getEntity();
if (null != entity) {
result = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset());
logger.info("执行请求完毕:" + result);
EntityUtils.consume(entity);
}
} catch (ConnectTimeoutException cte) {
logger.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
} catch (SocketTimeoutException ste) {
logger.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
} catch (ClientProtocolException cpe) {
logger.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
} catch (ParseException pe) {
logger.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
} catch (IOException ioe) {
logger.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
} catch (Exception e) {
logger.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
} finally {
try {
if (response != null)
response.close();
} catch (IOException e) {
e.printStackTrace();
}
if (httpPost != null) {
httpPost.releaseConnection();
}
}
return result;
} /**
* 上传文件
*
* @param url
* @param bodyBytes
* @param boundary
* @return
* @throws ClientProtocolException
* @throws IOException
*/
public static JSONObject uploadFile(String url, byte[] bodyBytes, String boundary) throws ClientProtocolException, IOException {
if (null != connManager) {
connManager.closeExpiredConnections();
connManager.closeIdleConnections(180L, TimeUnit.SECONDS);
}
JSONObject result = new JSONObject();
HttpPost post = new HttpPost(url);
post.setHeader(HttpHeaders.CONNECTION, "close");
RequestConfig requestConfig = doProxy(true, false);
post.setConfig(requestConfig);
post.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
post.setEntity(new ByteArrayEntity(bodyBytes));
CloseableHttpResponse response = null;
try {
response = httpClient.execute(post);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
HttpEntity entity = response.getEntity();
byte[] entityByte = EntityUtils.toByteArray(entity);
byte[] entityStr = AesUtil.decrypt(entityByte);
EntityUtils.consume(entity);
if (null != entityStr && entityStr.length > 0) {// 正常解密
result = JSONObject.fromObject(new String(entityStr, ENCODE_CHARSET));
} else {
// 解密失败
String s = new String(entityByte, ENCODE_CHARSET);
if (StringUtils.isNotBlank(s) && StringUtils.startsWith(s, "{")) {
result = JSONObject.fromObject(s);
} else {
result.put(ERROR_CODE, ERROR_EXCEPTION);
result.put(ERROR_MESSAGE, s);
}
}
return result;
} else {
result.put(ERROR_CODE, code);
result.put(ERROR_MESSAGE, "请求失败!");
}
} catch (Exception e) {
e.printStackTrace();
result.put(ERROR_CODE, ERROR_EXCEPTION);
result.put(ERROR_MESSAGE, e.getMessage());
} finally {
if (response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
if (post != null) {
post.releaseConnection();
}
}
return result;
} /**
* 正常httpclent请求
*
* @param reqURL
* @param json
* @param isProxy
* @return
*/
public static JSONObject sendPostRequest(String reqURL, JSONObject json, boolean isProxy) {
return sendPostRequestCommon(reqURL, json, isProxy, false);
} /**
* 加长传输时间httpclent请求
*
* @param reqURL
* @param json
* @param isProxy
* @return
*/
public static JSONObject sendPostRequestSlow(String reqURL, JSONObject json, boolean isProxy) {
return sendPostRequestCommon(reqURL, json, isProxy, true);
} /**
* 下载文件功能
*
* @param url
* @param json
* @return
*/
public static DownLoadFile downLoadFile(String url, String json) {
if (null != connManager) {
connManager.closeExpiredConnections();
connManager.closeIdleConnections(180L, TimeUnit.SECONDS);
}
byte[] encryptByte = AesUtil.encrypt(json);
HttpPost post = new HttpPost(url);
RequestConfig requestConfig = doProxy(true, false);
post.setHeader(HttpHeaders.CONNECTION, "close");
post.setConfig(requestConfig);
post.setEntity(new ByteArrayEntity(encryptByte));
CloseableHttpResponse response = null;
DownLoadFile file = new DownLoadFile();
try {
response = httpClient.execute(post);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
if (entity.getContentType().getValue().contains("application/octet-stream")) {
byte[] toByte = IOUtils.toByteArray(response.getEntity().getContent());
byte[] derByte = AesUtil.decrypt(toByte);
file.setError_code(0);
file.setError_message("ok");
file.setBytes(derByte);
file.setFileName(getFileName(response));
file.setContentType(entity.getContentType().getValue());
return file;
} else if (response.getEntity().getContentType().getValue().contains("text/plain")) {
byte[] entityByte = EntityUtils.toByteArray(response.getEntity());
byte[] entityStr = AesUtil.decrypt(entityByte);
JSONObject jsonResult;
if (null != entityStr && entityStr.length > 0) {
jsonResult = JSONObject.fromObject(new String(entityStr, ENCODE_CHARSET));
} else {
String s = new String(entityByte, ENCODE_CHARSET);
logger.info("下载文件返回的字符串是:{}", s);
jsonResult = JSONObject.fromObject(s);
}
file.setError_code(jsonResult.getInt(ERROR_CODE));
file.setError_message(jsonResult.getString(ERROR_MESSAGE));
return file;
}
}
} catch (Exception e) {
file.setError_code(ERROR_EXCEPTION);
file.setError_message(e.getMessage());
logger.error(e.getMessage(), e);
} finally {
if (response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
if (post != null) {
post.releaseConnection();
}
}
return file;
} /**
* 获取Header标头中的filename,文件名称
*
* @param response
* @return
*/
public static String getFileName(HttpResponse response) {
Header contentHeader = response.getFirstHeader("Content-Disposition");
String filename = null;
if (contentHeader != null) {
HeaderElement[] values = contentHeader.getElements();
if (values.length == 1) {
NameValuePair param = values[0].getParameterByName("filename");
if (param != null) {
try {
filename = new String(param.getValue().getBytes("iso-8859-1"), ENCODE_CHARSET);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return filename;
} /**
* 代理设置
*
* @param isProxy
* @return
*/
private static RequestConfig doProxy(boolean isProxy, boolean delay) {
RequestConfig.Builder configBuilder = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT);
if (delay) {
configBuilder.setSocketTimeout(SOCKET_TIMEOUT_DELAY);
}
if (CloudBootStrapUtils.PROXY_START && isProxy) {
HttpHost proxy = new HttpHost(CloudBootStrapUtils.PROXY_ADDRESS, CloudBootStrapUtils.PROXY_PORT);
configBuilder.setProxy(proxy);
}
return configBuilder.build();
} /**
* 发送post请求
*
* @param reqURL
* @param json
* @param isProxy
* @return
*/
private static JSONObject sendPostRequestCommon(String reqURL, JSONObject json, boolean isProxy, boolean delay) {
if (null != connManager) {
connManager.closeExpiredConnections();
connManager.closeIdleConnections(180L, TimeUnit.SECONDS);
}
PoolStats poolStats;
if (connManager != null && (poolStats = connManager.getTotalStats()) != null) {
if (poolStats.getLeased() > 100 || poolStats.getPending() > 1) {
logger.info("now client pool {}", poolStats);
}
}
JSONObject jsonResult = new JSONObject();
// 创建HTTP请求
HttpPost post = new HttpPost(reqURL);
post.setHeader(HttpHeaders.CONNECTION, "close");
// 参数AEC加密
byte[] encryptByte = AesUtil.encrypt(json.toString());
if (isProxy) {
RequestConfig requestConfig = doProxy(isProxy, delay);
if (null != requestConfig) {
post.setConfig(requestConfig);
}
}
// 设置访问字节型
post.setEntity(new ByteArrayEntity(encryptByte));
CloseableHttpResponse response = null;
try {
response = httpClient.execute(post);
HttpEntity entity = response.getEntity();
if (response.getStatusLine().getStatusCode() == 200 && null != entity) {
byte[] entityByte = EntityUtils.toByteArray(entity);
byte[] entityStr = AesUtil.decrypt(entityByte);
EntityUtils.consume(entity);
if (null != entityStr && entityStr.length > 0) {// 正常解密
jsonResult = JSONObject.fromObject(new String(entityStr, ENCODE_CHARSET));
} else {
// 解密失败
String s = new String(entityByte, ENCODE_CHARSET);
if (StringUtils.isNotBlank(s) && StringUtils.startsWith(s, "{")) {
jsonResult = JSONObject.fromObject(s);
} else {
jsonResult.put(ERROR_CODE, ERROR_EXCEPTION);
jsonResult.put(ERROR_MESSAGE, s);
}
}
return jsonResult;
}
jsonResult.put(ERROR_CODE, response.getStatusLine().getStatusCode());
jsonResult.put(ERROR_MESSAGE, response.getStatusLine().toString());
} catch (Exception e) {
jsonResult.put(ERROR_CODE, ERROR_EXCEPTION);
jsonResult.put(ERROR_MESSAGE, e.getMessage());
} finally {
if (response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
if (post != null) {
post.releaseConnection();
}
}
return jsonResult;
} /**
* SSL的socket工厂创建
*/
private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
SSLConnectionSocketFactory sslsf = null;
// 创建TrustManager() 用于解决javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
} @Override
public void checkClientTrusted(X509Certificate[] arg0, String authType) throws CertificateException {
} @Override
public void checkServerTrusted(X509Certificate[] arg0, String authType) throws CertificateException {
}
};
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
sslContext.init(null, new TrustManager[] { (TrustManager) trustManager }, null);
// 创建SSLSocketFactory , // 不校验域名 ,取代以前验证规则
sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return sslsf;
} /**
* httpclent连接池的状态
*
* @return
*/
public static Map<HttpRoute, PoolStats> getConnManagerStats() {
if (connManager != null) {
Set<HttpRoute> routeSet = connManager.getRoutes();
if (routeSet != null && !routeSet.isEmpty()) {
Map<HttpRoute, PoolStats> routeStatsMap = new HashMap<HttpRoute, PoolStats>();
for (HttpRoute route : routeSet) {
PoolStats stats = connManager.getStats(route);
routeStatsMap.put(route, stats);
}
return routeStatsMap;
}
}
return null;
} /**
* 获取当前连接池的状态
*
* @return
*/
public static PoolStats getConnManagerTotalStats() {
if (connManager != null) {
return connManager.getTotalStats();
}
return null;
} /**
* 关闭系统时关闭httpClient
*/
public static void releaseHttpClient() {
try {
httpClient.close();
} catch (IOException e) {
logger.error("关闭httpClient异常" + e);
} finally {
if (connManager != null) {
connManager.shutdown();
}
}
}
}

  

05-11 21:41