前言
在上一节中我们学习了如何生成X509-P7-DER秘钥对,并使用它们用于加签和解签。本节我将学习一下如何封装一些常用的HttpClient 方法。
概述
新建Maven项目,编写一些封装代码,为了展示方便我变一次性展示写好的代码
目录
代码
AsyncHttpClientCallback.java
package Util.HttpClientUtil; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.ParseException; import org.apache.http.client.utils.HttpClientUtils; import org.apache.http.concurrent.FutureCallback; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; /** * 被回调的对象,给异步的httpclient使用 * */ public class AsyncHttpClientCallback implements FutureCallback<HttpResponse> { private static Logger LOG = LoggerFactory.getLogger(AsyncHttpClientCallback.class); /** * 请求完成后调用该函数 */ @Override public void completed(HttpResponse response) { LOG.warn("status:{}", response.getStatusLine().getStatusCode()); LOG.warn("response:{}", getHttpContent(response)); HttpClientUtils.closeQuietly(response); } /** * 请求取消后调用该函数 */ @Override public void cancelled() { } /** * 请求失败后调用该函数 */ @Override public void failed(Exception e) { } protected String getHttpContent(HttpResponse response) { HttpEntity entity = response.getEntity(); String body = null; if (entity == null) { return null; } try { body = EntityUtils.toString(entity, "utf-8"); } catch (ParseException e) { LOG.warn("the response's content inputstream is corrupt", e); } catch (IOException e) { LOG.warn("the response's content inputstream is corrupt", e); } return body; } }
HttpAsyncClient.java
package Util.HttpClientUtil; import org.apache.http.Consts; import org.apache.http.HttpHost; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.ConnectionConfig; import org.apache.http.config.Lookup; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.impl.auth.*; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.impl.nio.reactor.IOReactorConfig; import org.apache.http.nio.conn.NoopIOSessionStrategy; import org.apache.http.nio.conn.SchemeIOSessionStrategy; import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.nio.reactor.IOReactorException; import javax.net.ssl.SSLContext; import java.nio.charset.CodingErrorAction; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; /** * 异步的HTTP请求对象,可设置代理 */ public class HttpAsyncClient { private static int socketTimeout = 1000;// 设置等待数据超时时间5秒钟 根据业务调整 private static int connectTimeout = 2000;// 连接超时 private static int poolSize = 3000;// 连接池最大连接数 private static int maxPerRoute = 1500;// 每个主机的并发最多只有1500 private static int connectionRequestTimeout = 3000; // 从连接池中后去连接的timeout时间 // http代理相关参数 private String host = ""; private int port = 0; private String username = ""; private String password = ""; // 异步httpclient private CloseableHttpAsyncClient asyncHttpClient; // 异步加代理的httpclient private CloseableHttpAsyncClient proxyAsyncHttpClient; public HttpAsyncClient() { try { this.asyncHttpClient = createAsyncClient(false); this.proxyAsyncHttpClient = createAsyncClient(true); } catch (Exception e) { e.printStackTrace(); } } public CloseableHttpAsyncClient createAsyncClient(boolean proxy) throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, MalformedChallengeException, IOReactorException { RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectionRequestTimeout) .setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build(); SSLContext sslcontext = SSLContexts.createDefault(); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password); CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, credentials); // 设置协议http和https对应的处理socket链接工厂的对象 Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create() .register("http", NoopIOSessionStrategy.INSTANCE) .register("https", new SSLIOSessionStrategy(sslcontext)).build(); // 配置io线程 IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoKeepAlive(false).setTcpNoDelay(true) .setIoThreadCount(Runtime.getRuntime().availableProcessors()).build(); // 设置连接池大小 ConnectingIOReactor ioReactor; ioReactor = new DefaultConnectingIOReactor(ioReactorConfig); PoolingNHttpClientConnectionManager conMgr = new PoolingNHttpClientConnectionManager(ioReactor, null, sessionStrategyRegistry, null); if (poolSize > 0) { conMgr.setMaxTotal(poolSize); } if (maxPerRoute > 0) { conMgr.setDefaultMaxPerRoute(maxPerRoute); } else { conMgr.setDefaultMaxPerRoute(10); } ConnectionConfig connectionConfig = ConnectionConfig.custom().setMalformedInputAction(CodingErrorAction.IGNORE) .setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8).build(); Lookup<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create() .register(AuthSchemes.BASIC, new BasicSchemeFactory()) .register(AuthSchemes.DIGEST, new DigestSchemeFactory()) .register(AuthSchemes.NTLM, new NTLMSchemeFactory()) .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory()) .register(AuthSchemes.KERBEROS, new KerberosSchemeFactory()).build(); conMgr.setDefaultConnectionConfig(connectionConfig); if (proxy) { return HttpAsyncClients.custom().setConnectionManager(conMgr) .setDefaultCredentialsProvider(credentialsProvider).setDefaultAuthSchemeRegistry(authSchemeRegistry) .setProxy(new HttpHost(host, port)).setDefaultCookieStore(new BasicCookieStore()) .setDefaultRequestConfig(requestConfig).build(); } else { return HttpAsyncClients.custom().setConnectionManager(conMgr) .setDefaultCredentialsProvider(credentialsProvider).setDefaultAuthSchemeRegistry(authSchemeRegistry) .setDefaultCookieStore(new BasicCookieStore()).build(); } } public CloseableHttpAsyncClient getAsyncHttpClient() { return asyncHttpClient; } public CloseableHttpAsyncClient getProxyAsyncHttpClient() { return proxyAsyncHttpClient; } }
HttpClientFactory.java
package Util.HttpClientUtil; /** * * httpclient 工厂类 */ public class HttpClientFactory { private static HttpAsyncClient httpAsyncClient = new HttpAsyncClient(); private static HttpSyncClient httpSyncClient = new HttpSyncClient(); private static OkClient okClient = new OkClient(); private HttpClientFactory() { } private static HttpClientFactory httpClientFactory = new HttpClientFactory(); public static HttpClientFactory getInstance() { return httpClientFactory; } protected HttpAsyncClient getHttpAsyncClientPool() { return httpAsyncClient; } protected HttpSyncClient getHttpSyncClientPool() { return httpSyncClient; } protected OkClient getOkClientPool() { return okClient; } }
HttpClientUtil.java
package Util.HttpClientUtil; import okhttp3.*; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; 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.concurrent.FutureCallback; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; import java.util.List; import java.util.Map; /** * * http client 业务逻辑处理类 */ public class HttpClientUtil { private static Logger LOG = LoggerFactory.getLogger(HttpClientUtil.class); private static String utf8Charset = "utf-8"; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); /** * 向指定的url发送一次post请求,参数是List<NameValuePair> * * @param baseUrl * 请求地址 * @param list * 请求参数,格式是List<NameValuePair> * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static String httpSyncPost(String baseUrl, List<BasicNameValuePair> list) { CloseableHttpClient httpClient = HttpClientFactory.getInstance().getHttpSyncClientPool().getHttpClient(); HttpPost httpPost = new HttpPost(baseUrl); // Parameters LOG.warn("==== Parameters ======" + list); CloseableHttpResponse response = null; try { httpPost.setEntity(new UrlEncodedFormEntity(list)); // httpPost.setHeader("Connection","close"); response = httpClient.execute(httpPost); LOG.warn("========HttpResponseProxy:========" + response.getStatusLine()); HttpEntity entity = response.getEntity(); String result = null; if (entity != null) { result = EntityUtils.toString(entity, "UTF-8"); LOG.warn("========Response=======" + result); } EntityUtils.consume(entity); return result; } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 向指定的url发送一次post请求,参数是字符串 * * @param baseUrl * 请求地址 * @param postString * 请求参数,格式是json.toString() * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestBody接收参数 */ public static String httpSyncPost(String baseUrl, String postString) { CloseableHttpClient httpClient = HttpClientFactory.getInstance().getHttpSyncClientPool().getHttpClient(); HttpPost httpPost = new HttpPost(baseUrl); // parameters LOG.warn("==== Parameters ======" + postString); CloseableHttpResponse response = null; try { if (postString == null || "".equals(postString)) { throw new Exception("missing post String"); } StringEntity stringEntity = new StringEntity(postString.toString(), utf8Charset); stringEntity.setContentEncoding("UTF-8"); stringEntity.setContentType("application/json"); httpPost.setEntity(stringEntity); response = httpClient.execute(httpPost); LOG.warn("========HttpResponseProxy:========" + response.getStatusLine()); HttpEntity entity = response.getEntity(); String result = null; if (entity != null) { result = EntityUtils.toString(entity, "UTF-8"); LOG.warn("========Response=======" + result); } EntityUtils.consume(entity); return result; } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 向指定的url发送一次get请求,参数是List<NameValuePair> * * @param baseUrl * 请求地址 * @param list * 请求参数,格式是List<NameValuePair> * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static String httpSyncGet(String baseUrl, List<BasicNameValuePair> list) { CloseableHttpClient httpClient = HttpClientFactory.getInstance().getHttpSyncClientPool().getHttpClient(); HttpGet httpGet = new HttpGet(baseUrl); // Parameters LOG.warn("==== Parameters ======" + list); CloseableHttpResponse response = null; try { if (list != null) { String getUrl = EntityUtils.toString(new UrlEncodedFormEntity(list)); httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + getUrl)); } else { httpGet.setURI(new URI(httpGet.getURI().toString())); } response = httpClient.execute(httpGet); LOG.warn("========HttpResponseProxy:========" + response.getStatusLine()); HttpEntity entity = response.getEntity(); String result = null; if (entity != null) { result = EntityUtils.toString(entity, "UTF-8"); LOG.warn("========Response=======" + result); } EntityUtils.consume(entity); return result; } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 向指定的url发送一次get请求,参数是字符串 * * @param baseUrl * 请求地址 * @param urlParams * 请求参数,格式是String * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static String httpSyncGet(String baseUrl, String urlParams) { CloseableHttpClient httpClient = HttpClientFactory.getInstance().getHttpSyncClientPool().getHttpClient(); HttpGet httpGet = new HttpGet(baseUrl); // Parameters LOG.warn("==== Parameters ======" + urlParams); CloseableHttpResponse response = null; try { if (null != urlParams || "".equals(urlParams)) { httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + urlParams)); } else { httpGet.setURI(new URI(httpGet.getURI().toString())); } response = httpClient.execute(httpGet); LOG.warn("========HttpResponseProxy:========" + response.getStatusLine()); HttpEntity entity = response.getEntity(); String result = null; if (entity != null) { result = EntityUtils.toString(entity, "UTF-8"); LOG.warn("========Response=======" + result); } EntityUtils.consume(entity); return result; } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 向指定的url发送一次get请求,参数是字符串 * * @param baseUrl * 请求地址 * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static String httpSyncGet(String baseUrl) { CloseableHttpClient httpClient = HttpClientFactory.getInstance().getHttpSyncClientPool().getHttpClient(); HttpGet httpGet = new HttpGet(baseUrl); CloseableHttpResponse response = null; try { httpGet.setURI(new URI(httpGet.getURI().toString())); response = httpClient.execute(httpGet); LOG.warn("========HttpResponseProxy:========" + response.getStatusLine()); HttpEntity entity = response.getEntity(); String result = null; if (entity != null) { result = EntityUtils.toString(entity, "UTF-8"); LOG.warn("========Response=======" + result); } EntityUtils.consume(entity); return result; } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 向指定的url发送一次异步post请求,参数是字符串 * * @param baseUrl * 请求地址 * @param postString * 请求参数,格式是json.toString() * @param urlParams * 请求参数,格式是String * @param callback * 回调方法,格式是FutureCallback * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static void httpAsyncPost(String baseUrl, String postString, String urlParams, FutureCallback<HttpResponse> callback) throws Exception { if (baseUrl == null || "".equals(baseUrl)) { LOG.warn("we don't have base url, check config"); throw new Exception("missing base url"); } CloseableHttpAsyncClient hc = HttpClientFactory.getInstance().getHttpAsyncClientPool().getAsyncHttpClient(); try { hc.start(); HttpPost httpPost = new HttpPost(baseUrl); // httpPost.setHeader("Connection","close"); if (null != postString) { LOG.debug("exeAsyncReq post postBody={}", postString); StringEntity entity = new StringEntity(postString.toString(), utf8Charset); entity.setContentEncoding("UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); } if (null != urlParams) { httpPost.setURI(new URI(httpPost.getURI().toString() + "?" + urlParams)); } LOG.warn("exeAsyncReq getparams:" + httpPost.getURI()); hc.execute(httpPost, callback); } catch (Exception e) { e.printStackTrace(); } } /** * 向指定的url发送一次异步post请求,参数是字符串 * * @param baseUrl * 请求地址 * @param urlParams * 请求参数,格式是List<BasicNameValuePair> * @param callback * 回调方法,格式是FutureCallback * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static void httpAsyncPost(String baseUrl, List<BasicNameValuePair> postBody, List<BasicNameValuePair> urlParams, FutureCallback<HttpResponse> callback) throws Exception { if (baseUrl == null || "".equals(baseUrl)) { LOG.warn("we don't have base url, check config"); throw new Exception("missing base url"); } try { CloseableHttpAsyncClient hc = HttpClientFactory.getInstance().getHttpAsyncClientPool().getAsyncHttpClient(); hc.start(); HttpPost httpPost = new HttpPost(baseUrl); // httpPost.setHeader("Connection","close"); if (null != postBody) { LOG.debug("exeAsyncReq post postBody={}", postBody); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postBody, "UTF-8"); httpPost.setEntity(entity); } if (null != urlParams) { String getUrl = EntityUtils.toString(new UrlEncodedFormEntity(urlParams)); httpPost.setURI(new URI(httpPost.getURI().toString() + "?" + getUrl)); } LOG.warn("exeAsyncReq getparams:" + httpPost.getURI()); hc.execute(httpPost, callback); } catch (Exception e) { e.printStackTrace(); } } /** * 向指定的url发送一次异步get请求,参数是String * * @param baseUrl * 请求地址 * @param urlParams * 请求参数,格式是String * @param callback * 回调方法,格式是FutureCallback * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static void httpAsyncGet(String baseUrl, String urlParams, FutureCallback<HttpResponse> callback) throws Exception { if (baseUrl == null || "".equals(baseUrl)) { LOG.warn("we don't have base url, check config"); throw new Exception("missing base url"); } CloseableHttpAsyncClient hc = HttpClientFactory.getInstance().getHttpAsyncClientPool().getAsyncHttpClient(); try { hc.start(); HttpGet httpGet = new HttpGet(baseUrl); // httpGet.setHeader("Connection","close"); if (null != urlParams || "".equals(urlParams)) { httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + urlParams)); } else { httpGet.setURI(new URI(httpGet.getURI().toString())); } LOG.warn("exeAsyncReq getparams:" + httpGet.getURI()); hc.execute(httpGet, callback); } catch (Exception e) { e.printStackTrace(); } } /** * 向指定的url发送一次异步get请求,参数是List<BasicNameValuePair> * * @param baseUrl * 请求地址 * @param urlParams * 请求参数,格式是List<BasicNameValuePair> * @param callback * 回调方法,格式是FutureCallback * @return 返回结果,请求失败时返回null * @apiNote http接口处用 @RequestParam接收参数 */ public static void httpAsyncGet(String baseUrl, List<BasicNameValuePair> urlParams, FutureCallback<HttpResponse> callback) throws Exception { if (baseUrl == null || "".equals(baseUrl)) { LOG.warn("we don't have base url, check config"); throw new Exception("missing base url"); } try { CloseableHttpAsyncClient hc = HttpClientFactory.getInstance().getHttpAsyncClientPool().getAsyncHttpClient(); hc.start(); HttpPost httpGet = new HttpPost(baseUrl); // httpGet.setHeader("Connection","close"); if (null != urlParams) { String getUrl = EntityUtils.toString(new UrlEncodedFormEntity(urlParams)); httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + getUrl)); } LOG.warn("exeAsyncReq getparams:" + httpGet.getURI()); hc.execute(httpGet, callback); } catch (Exception e) { e.printStackTrace(); } } public static String OkSyncPost(String url, String json) throws IOException { OkHttpClient okClient = HttpClientFactory.getInstance().getOkClientPool().getHttpClient(); RequestBody body = RequestBody.create(JSON, json); Request request = new Request.Builder().url(url).post(body).build(); try (Response response = okClient.newCall(request).execute()) { return response.body().string(); } } public static void OkAsyncPost(String url, String json) throws IOException { OkHttpClient okClient = HttpClientFactory.getInstance().getOkClientPool().getHttpClient(); RequestBody body = RequestBody.create(JSON, json); Request request = new Request.Builder().url(url).post(body).build(); Call call = okClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { LOG.warn("OkAsyncPost回调:" + response.body().string()); } }); } public static void OkAsyncPost(String url, Map<String, String> map) throws IOException { OkHttpClient okClient = HttpClientFactory.getInstance().getOkClientPool().getHttpClient(); FormBody.Builder formBodyBuilder = new FormBody.Builder(); for (Map.Entry<String, String> entry : map.entrySet()) { formBodyBuilder.add(entry.getKey(), entry.getValue()); } Request request = new Request.Builder().url(url).post(formBodyBuilder.build()).build(); Call call = okClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { LOG.warn("OkAsyncPost回调:" + response.body().string()); } }); } public static void OkAsyncPost(String url, Map<String, String> map, Callback callback) throws IOException { OkHttpClient okClient = HttpClientFactory.getInstance().getOkClientPool().getHttpClient(); FormBody.Builder formBodyBuilder = new FormBody.Builder(); for (Map.Entry<String, String> entry : map.entrySet()) { formBodyBuilder.add(entry.getKey(), entry.getValue()); } Request request = new Request.Builder().url(url).post(formBodyBuilder.build()).build(); Call call = okClient.newCall(request); call.enqueue(callback); } public static String OkSyncGet(String url) throws IOException { OkHttpClient okClient = HttpClientFactory.getInstance().getOkClientPool().getHttpClient(); Request request = new Request.Builder().url(url).build(); try (Response response = okClient.newCall(request).execute()) { return response.body().string(); } } public static void OkAsyncGet(String url) throws IOException { OkHttpClient okClient = HttpClientFactory.getInstance().getOkClientPool().getHttpClient(); Request request = new Request.Builder().url(url).build(); Call call = okClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { LOG.warn("OkAsyncGet回调:" + response.body().string()); } }); } }
HttpSyncClient.java
package Util.HttpClientUtil; import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; 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.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContexts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; /** * 同步的HTTP请求对象,支持post与get方法以及可设置代理 */ public class HttpSyncClient { private Logger logger = LoggerFactory.getLogger(HttpSyncClient.class); private PoolingHttpClientConnectionManager poolConnManager; private final int maxTotalPool = 200;// 连接池最大连接数 private final int maxConPerRoute = 20;// 每个主机的并发最多只有20 private final int socketTimeout = 2000;// 设置等待数据超时时间5秒钟 根据业务调整 private final int connectionRequestTimeout = 3000; private final int connectTimeout = 1000;// 连接超时 // 同步httpclient private CloseableHttpClient httpClient; public HttpSyncClient() { try { this.httpClient = init(); } catch (Exception e) { e.printStackTrace(); } } public CloseableHttpClient init() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(); HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf).build(); poolConnManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); // Increase max total connection to 200 poolConnManager.setMaxTotal(maxTotalPool); // Increase default max connection per route to 20 poolConnManager.setDefaultMaxPerRoute(maxConPerRoute); SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(socketTimeout).build(); poolConnManager.setDefaultSocketConfig(socketConfig); RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectionRequestTimeout) .setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build(); CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(poolConnManager) .setDefaultRequestConfig(requestConfig).build(); if (poolConnManager != null && poolConnManager.getTotalStats() != null) { logger.info("now client pool " + poolConnManager.getTotalStats().toString()); } return httpClient; } public CloseableHttpClient getHttpClient() { return httpClient; } }
OkClient.java
package Util.HttpClientUtil; import okhttp3.*; public class OkClient { private static OkHttpClient client = new OkHttpClient(); public OkHttpClient getHttpClient() { return client; } String bowlingJson(String player1, String player2) { return "{'winCondition':'HIGH_SCORE'," + "'name':'Bowling'," + "'round':4," + "'lastSaved':1367702411696," + "'dateStarted':1367702378785," + "'players':[" + "{'name':'" + player1 + "','history':[10,8,6,7,8],'color':-13388315,'total':39}," + "{'name':'" + player2 + "','history':[6,10,5,10,10],'color':-48060,'total':41}" + "]}"; } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.maizi</groupId> <artifactId>HttpAsyncClientUtils</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> <properties> <!-- log4j日志包版本号 --> <slf4j.version>1.7.25</slf4j.version> <log4j.version>2.8.2</log4j.version> </properties> <dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.3.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpasyncclient</artifactId> <version>4.1.3</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j --> <!--用log4j接管commons-logging --> <!-- log配置:Log4j2 + Slf4j --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <!-- 桥接:告诉Slf4j使用Log4j2 --> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <!-- 桥接:告诉commons logging使用Log4j2 --> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.39</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.9.0</version> </dependency> <dependency> <groupId>com.google.http-client</groupId> <artifactId>google-http-client</artifactId> <version>1.22.0</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> </dependencies> </project>
HttpClientDemo.java
package Test; import Util.HttpClientUtil.AsyncHttpClientCallback; import Util.HttpClientUtil.HttpClientUtil; import com.alibaba.fastjson.JSONObject; import org.apache.http.message.BasicNameValuePair; import java.util.ArrayList; import java.util.List; /** * http client 使用 */ public class HttpClientDemo extends HttpClientUtil { public static void main(String[] args) { new HttpClientDemo().getResult(); } public void getResult() { String url = ""; String urlParams = "id=1"; JSONObject json = new JSONObject(); json.put("id", "1"); List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>(); list.add(new BasicNameValuePair("id", "1")); JSONObject header = new JSONObject(); JSONObject request = new JSONObject(); request.put("inBody", inBody); request.put("reqHeader", header); try { //httpSyncPost(url,list); httpSyncPost(url, request.toString()); // httpSyncGet(url,list); // httpSyncGet(url,urlParams); //httpAsyncPost(url, json.toString(), urlParams, new AsyncHttpClientCallback()); // httpAsyncPost(url, list, list, new AsyncHttpClientCallback()); // httpAsyncGet(url, urlParams, new AsyncHttpClientCallback()); // httpAsyncGet(url, list, new AsyncHttpClientCallback()); //System.out.println(SslTest.postRequest(url, request.toString(), 150000)); } catch (Exception e) { e.printStackTrace(); } } }
小结
- 本节封装的方法基本能涵盖常用的HttpClient请求包括同步和异步请求,并且还能在性能方面有显著的提升。
- 在一些特殊的场景下,该封装方法便不再适用了,比如HttpClient的请求的URL需要SSL证书认证,那么如果使用如上封装的方法请求将无法到达,且容易出现一些未知异常,下一节我们将学习一下如何使用一些手段绕过SSL的证书认证。