不废话,直接上代码,复制即用,拿走不谢!
必要导包:
Maven依赖如下:
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
package com.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
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.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
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.SSLConnectionSocketFactory;
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.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
/**
* @ClassName: HttpConnectUtil
* @Description:公用HttpUtil
* @author weny.yang
* @date Sep 4, 2020
*/
public class HttpConnectUtil {
private static Log log = LogFactory.getLog(HttpConnectUtil.class);
// 连接超时
private static final int CONNECT_TIME_OUT = 1 * 1000;
// 读取超时
private static final int SOCKET_TIME_OUT = 3 * 1000;
// 连接池获取连接超时
private static final int CONNECT_REQUST_TIME_OUT = 1 * 1000;
// 单例client
private static CloseableHttpClient httpClient = null;
// 同步锁
private final static Object syncLock = new Object();
// 最大重试次数
private final static int RETRY_TIMES = 5;
private HttpURLConnection conn;
private SSLSocketFactory ssf = (SSLSocketFactory)SSLSocketFactory.getDefault();
/**
* @Title: doGet
* @Description:get请求, isSSL是否是SSL安全协议
* @author weny.yang
*/
public String doGet(String urlStr, boolean isSSL) {
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
if(isSSL) {
((HttpsURLConnection) conn).setSSLSocketFactory(ssf); //设置https
}
conn.setRequestProperty("Connection", "Keep-Alive"); // 设置长链接
conn.setConnectTimeout(1000); // 设置连接超时
conn.setReadTimeout(500); // 设置读取超时
conn.setRequestMethod("GET"); // 提交参数
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
StringBuilder result = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
result.append(line).append("\n");
}
return result.toString().trim();
}
} catch (Exception e) {
log.error("[HttpConnectUtil] doGet() 异常: " + e);
}
return "";
}
/**
* @Title: doPost
* @Description:post请求
* @author weny.yang
* @date Sep 8, 2020
*/
public String doPost(String url,Map<String,Object> params) {
String result = "";
//建立HttpPost对象
HttpPost httpPost = new HttpPost(url);
//对http请求协议进行相关配置
config(httpPost);
//设置post请求参数
setPostParams(httpPost, params);
//CloseableHttpResponse extends HttpResponse
CloseableHttpResponse response = null;
try {
//获取HttpClient对象
CloseableHttpClient client = getHttpClient(url);
response = client.execute(httpPost, HttpClientContext.create());
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
EntityUtils.consume(entity);
} catch (Exception e) {
log.error("[HttpConnectUtil] doPost() 异常: " + e);
} finally {
try {
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
log.error("[HttpConnectUtil] doPost() 异常: " + e);
}
}
return result.trim();
}
/**
* @Title: config
* @Description:对http请求协议进行相关配置
* @author weny.yang
* @date Sep 7, 2020
* HttpPost extends HttpEntityEnclosingRequestBase extends HttpRequestBase
*
*/
private static void config(HttpRequestBase httpRequestBase) {
// 配置超时时间
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECT_REQUST_TIME_OUT)
.setConnectTimeout(CONNECT_TIME_OUT).setSocketTimeout(SOCKET_TIME_OUT).build();
httpRequestBase.setConfig(requestConfig);
}
/**
* @Title: setPostParams
* @Description:设置post请求参数
* @author weny.yang
* @date Sep 7, 2020
*
* NameValuePair(简单名称值对节点类型)
*/
private static void setPostParams(HttpPost httpost, Map<String, Object> params) {
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (String key : params.keySet()) {
nvps.add(new BasicNameValuePair(key, params.get(key).toString()));
}
try {
httpost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
} catch (UnsupportedEncodingException e) {
log.error("[HttpConnectUtil] setPostParams() 异常: " + e);
}
}
/**
* @Title: getHttpClient
* @Description:获取HttpClient对象
* @author weny.yang
* @date Sep 8, 2020
*/
private static CloseableHttpClient getHttpClient(String url) {
String hostname = url.split("/")[2];
int port = 80;
if (hostname.contains(":")) {
String[] arr = hostname.split(":");
hostname = arr[0];
port = Integer.parseInt(arr[1]);
}
//单例模式
if (httpClient == null) {
synchronized (syncLock) {//同步锁
if (httpClient == null) {
httpClient = createHttpClient(200, 40, 100, hostname, port);
}
}
}
return httpClient;
}
/**
* @Title: 创建HttpClient对象
* @Description:
* @author weny.yang
* @date Sep 9, 2020
*/
private static CloseableHttpClient createHttpClient(int maxTotal, int maxPerRoute, int maxRoute, String hostname, int port) {
ConnectionSocketFactory pcsf = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslcsf = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", pcsf).register("https", sslcsf).build();
//创建HttpClient连接管理池
PoolingHttpClientConnectionManager phccm = new PoolingHttpClientConnectionManager(registry);
// 最大连接数
phccm.setMaxTotal(maxTotal);
// 每个默认基础路由的连接数
phccm.setDefaultMaxPerRoute(maxPerRoute);
HttpHost httpHost = new HttpHost(hostname, port);
// 每个路由的最大连接数增加
phccm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute);
SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).build();
phccm.setDefaultSocketConfig(socketConfig);
// 请求重试处理
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= RETRY_TIMES) { // 最大重试次数
return false;
}
if (exception instanceof NoHttpResponseException) { // 服务器丢掉连接
return true;
}
if (exception instanceof SSLHandshakeException) { // SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) { // 超时
return false;
}
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;
}
};
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(phccm).setRetryHandler(httpRequestRetryHandler).build();
return httpClient;
}
/**
* @Title: main
* @Description:测试类
* @author weny.yang
*/
public static void main(String[] args) {
HttpConnectUtil util = new HttpConnectUtil();
System.out.println(util.doGet("http://quan.suning.com/getSysTime.do", false));
}
}
使用以下是三个获取时间的测试接口地址进行测试,某宝速度比较优秀,某宁也还行,某讯垃圾,直接502,具体输出如下:
某宝:http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp
某宁:http://quan.suning.com/getSysTime.do
某讯: http://cgi.im.qq.com/cgi-bin/cgi_svrtime
运行输出: