基于HttpClient接口开发实例(三)

前言


在上一节中我们学习了如何生成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的证书认证。

猜你喜欢

转载自blog.csdn.net/u012437781/article/details/80019484