使用背景:
因项目使用非结构化存储,http相关jar包统一升级到httpClient4.5.2,查阅相关文档总结如下,以咨分享,望不吝指教。
依赖jar包
httpclient-4.5.2.jar、httpcore-4.4.4.jar、sl4j.jar
HttpClientUtil.java
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; 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.HashMap; import java.util.List; import java.util.Map; 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.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpStatus; 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.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.conn.ConnectTimeoutException; 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.conn.ssl.TrustSelfSignedStrategy; 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.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.DefaultProxyRoutePlanner; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HttpContext; import org.apache.http.ssl.SSLContexts; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 参考:https://www.cnblogs.com/luken2017/p/6386055.html * https://www.2cto.com/net/201709/681448.html * https://www.cnblogs.com/likaitai/p/5431246.html */ public class HttpClientUtil { private static final Logger LOG = LoggerFactory.getLogger(HttpClientUtil.class); /** 连接池 */ private static PoolingHttpClientConnectionManager connManager = null; // 代理信息 private static final String PROXY_IP = "10.5.3.9"; private static final int PROXY_PORT = 80; private static int maxTotalPool = 1000; private static int maxConPerRoute = 20; private static int allTimeout = 15000; private static HashMap<String, HttpClientUtil> map = new HashMap<>(); private static Object object = new Object(); private String url = null; private CloseableHttpClient httpClient = null; public static HttpClientUtil getInstance(String strUrl) { HttpClientUtil instance = null; if ((instance = map.get(strUrl)) == null) { synchronized (object) { initConnManager(); instance = new HttpClientUtil(); instance.httpClient = getHttpClient(false, allTimeout); instance.url = strUrl; map.put(strUrl, instance); } } return instance; } public static HttpClientUtil getProxyInstance(String strUrl) { HttpClientUtil instance = null; if ((instance = map.get(strUrl)) == null) { synchronized (object) { initConnManager(); instance = new HttpClientUtil(); instance.httpClient = getHttpClient(true, allTimeout); instance.url = strUrl; map.put(strUrl, instance); } } return instance; } public static void initConnManager() { if (connManager == null) { // 创建ssl安全访问连接 // 获取创建ssl上下文对象 try { SSLContext sslContext = getSSLContext(true, null, null); // 注册 Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslContext)).build(); // ssl注册到连接池 connManager = new PoolingHttpClientConnectionManager(registry); connManager.setMaxTotal(maxTotalPool); // 连接池最大连接数 connManager.setDefaultMaxPerRoute(maxConPerRoute); // 每个路由最大连接数 } catch (Exception e) { LOG.error(e.getMessage(), e); } } } private static SSLContext getSSLContext(boolean isDeceive, File creFile, String crePwd) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, IOException { SSLContext sslContext = null; if (isDeceive) { sslContext = SSLContext.getInstance("SSLv3"); // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法 X509TrustManager x509TrustManager = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // Do nothing } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // Do nothing } @Override public X509Certificate[] getAcceptedIssuers() { // Do nothing return new X509Certificate[0]; } }; sslContext.init(null, new TrustManager[] { x509TrustManager }, null); } else { if (null != creFile && creFile.length() > 0) { if (null != crePwd) { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(new FileInputStream(creFile), crePwd.toCharArray()); sslContext = SSLContexts.custom().loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()) .build(); } else { throw new SSLHandshakeException("整数密码为空"); } } } return sslContext; } public static CloseableHttpClient getHttpClient(boolean startProxy, int timeout) { return getHttpClient(startProxy, timeout, timeout, timeout); } private static CloseableHttpClient getHttpClient(boolean startProxy, int connectionRquestTimeout, int connectTimeout, int socketTimeout) { // 配置请求参数 RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(connectionRquestTimeout) .setConnectTimeout(connectTimeout) .setSocketTimeout(socketTimeout) .build(); // 配置超时回调机制 HttpRequestRetryHandler retryHandler = 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(); // 如果请求是幂等的,就再次尝试 return !(request instanceof HttpEntityEnclosingRequest) ? true : false; } }; HttpClientBuilder httpClientBuilder = HttpClients.custom(); httpClientBuilder.setConnectionManager(connManager).setDefaultRequestConfig(requestConfig) .setRetryHandler(retryHandler); if (startProxy) { HttpHost proxy = new HttpHost(PROXY_IP, PROXY_PORT); DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); httpClientBuilder.setRoutePlanner(routePlanner); } return httpClientBuilder.build(); } public String postJson(String json) { HttpPost post = new HttpPost(url); StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); post.setEntity(entity); String responseContent = null; CloseableHttpResponse response = null; try { response = httpClient.execute(post); int status = response.getStatusLine().getStatusCode(); printStatus(status); if (status == HttpStatus.SC_OK) { responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8.name()); } } catch (IOException e) { LOG.error(e.getMessage(), e); } finally { post.abort(); post.releaseConnection(); if (response != null) { try { EntityUtils.consume(response.getEntity()); response.close(); } catch (IOException e) { LOG.error(e.getMessage(), e); } } } return responseContent; } /** * 发送 GET 请求(HTTP),不带输入数据 * * @param url * @return */ public String doGet(String url) { return doGet(new HashMap<String, Object>()); } /** * 发送 GET 请求(HTTP),K-V形式 * * @param url * @param params * @return */ public String doGet(Map<String, Object> params) { String apiUrl = url; StringBuilder param = new StringBuilder(); int i = 0; for (Map.Entry<String, Object> entry : params.entrySet()) { if (i == 0) { param.append("?"); } else { param.append("&"); } param.append(entry.getKey()).append("=").append(entry.getValue()); i++; } apiUrl += param; String result = null; CloseableHttpResponse response = null; HttpGet httpGet = null; try { httpGet = new HttpGet(apiUrl); response = httpClient.execute(httpGet); int status = response.getStatusLine().getStatusCode(); printStatus(status); if (status == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { result = EntityUtils.toString(response.getEntity(), Consts.UTF_8.name()); } } } catch (IOException e) { LOG.error(e.getMessage(), e); } finally { httpGet.abort(); httpGet.releaseConnection(); if (response != null) { try { EntityUtils.consume(response.getEntity()); response.close(); } catch (IOException e) { LOG.error(e.getMessage(), e); } } } return result; } /** * 发送 POST 请求(HTTP),K-V形式 * * @param url * 接口URL * @param params * 参数map * @return */ public String doPost(Map<String, String> params) { String result = null; HttpPost httpPost = new HttpPost(url); CloseableHttpResponse response = null; try { List<NameValuePair> pairList = new ArrayList<>(params.size()); for (Map.Entry<String, String> entry : params.entrySet()) { NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue()); pairList.add(pair); } httpPost.setEntity(new UrlEncodedFormEntity(pairList, Consts.UTF_8.name())); response = httpClient.execute(httpPost); int status = response.getStatusLine().getStatusCode(); printStatus(status); if (status == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { result = EntityUtils.toString(response.getEntity(), Consts.UTF_8.name()); } } } catch (IOException e) { LOG.error(e.getMessage(), e); } finally { httpPost.abort(); httpPost.releaseConnection(); if (response != null) { try { EntityUtils.consume(response.getEntity()); response.close(); } catch (IOException e) { LOG.error(e.getMessage(), e); } } } return result; } private void printStatus(int status) { LOG.info("返回状态:{}", status); } }