Http和Https网络同步请求httpclient和异步请求async-http-client

原文:https://blog.csdn.net/fengshizty/article/details/53100694

 

Http和https网络请求

    主要总结一下使用到的网络请求框架,一种是同步网络请求org.apache.httpcomponents的httpclient,另一种是异步网络请求com.ning的async-http-client,总结一下常用的http请求方式封装使用,如post、get、put、delete等,以及涉及到ssl证书https请求的双向证书验证。

    一、apache同步请求httpclient

    1、引入文件

    

[java] view plain copy
 
  1. <dependency>  
  2.             <groupId>org.apache.httpcomponents</groupId>  
  3.             <artifactId>httpclient</artifactId>  
  4.             <version>4.5.2</version>  
  5.         </dependency>  

 

 

    2、http和https的方法封装

    涉及常用的post和get的请求,https的ssl双向证书验证。

   

[java] view plain copy
 
  1. import java.io.IOException;  
  2. import java.io.UnsupportedEncodingException;  
  3. import java.net.URLEncoder;  
  4. import java.security.KeyStore;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8. import java.util.Map.Entry;  
  9.   
  10. import javax.net.ssl.SSLContext;  
  11.   
  12. import org.apache.http.NameValuePair;  
  13. import org.apache.http.client.config.RequestConfig;  
  14. import org.apache.http.client.entity.UrlEncodedFormEntity;  
  15. import org.apache.http.client.methods.CloseableHttpResponse;  
  16. import org.apache.http.client.methods.HttpGet;  
  17. import org.apache.http.client.methods.HttpPost;  
  18. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
  19. import org.apache.http.entity.StringEntity;  
  20. import org.apache.http.impl.client.CloseableHttpClient;  
  21. import org.apache.http.impl.client.HttpClients;  
  22. import org.apache.http.message.BasicNameValuePair;  
  23. import org.apache.http.ssl.SSLContexts;  
  24. import org.apache.http.util.EntityUtils;  
  25. import org.springframework.core.io.ClassPathResource;  
  26. import org.springframework.core.io.Resource;  
  27.   
  28. /** 
  29.  * 创建时间:2016年11月9日 下午4:16:32 
  30.  *  
  31.  * @author andy 
  32.  * @version 2.2 
  33.  */  
  34. public class HttpUtils {  
  35.   
  36.     private static final String DEFAULT_CHARSET = "UTF-8";  
  37.       
  38.     private static final int CONNECT_TIME_OUT = 5000; //链接超时时间3秒  
  39.       
  40.     private static final RequestConfig REQUEST_CONFIG = RequestConfig.custom().setConnectTimeout(CONNECT_TIME_OUT).build();  
  41.       
  42.     private static SSLContext wx_ssl_context = null; //微信支付ssl证书  
  43.       
  44.     static{  
  45.         Resource resource = new ClassPathResource("wx_apiclient_cert.p12");  
  46.         try {  
  47.             KeyStore keystore = KeyStore.getInstance("PKCS12");  
  48.             char[] keyPassword = ConfigUtil.getProperty("wx.mchid").toCharArray(); //证书密码  
  49.             keystore.load(resource.getInputStream(), keyPassword);  
  50.             wx_ssl_context = SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();  
  51.         } catch (Exception e) {  
  52.             e.printStackTrace();  
  53.         }  
  54.     }  
  55.   
  56.     /** 
  57.      * @description 功能描述: get 请求 
  58.      * @param url 请求地址 
  59.      * @param params 参数 
  60.      * @param headers headers参数 
  61.      * @return 请求失败返回null 
  62.      */  
  63.     public static String get(String url, Map<String, String> params, Map<String, String> headers) {  
  64.   
  65.         CloseableHttpClient httpClient = null;  
  66.         if (params != null && !params.isEmpty()) {  
  67.             StringBuffer param = new StringBuffer();  
  68.             boolean flag = true; // 是否开始  
  69.             for (Entry<String, String> entry : params.entrySet()) {  
  70.                 if (flag) {  
  71.                     param.append("?");  
  72.                     flag = false;  
  73.                 } else {  
  74.                     param.append("&");  
  75.                 }  
  76.                 param.append(entry.getKey()).append("=");  
  77.                   
  78.                 try {  
  79.                     param.append(URLEncoder.encode(entry.getValue(), DEFAULT_CHARSET));  
  80.                 } catch (UnsupportedEncodingException e) {  
  81.                     //编码失败  
  82.                 }  
  83.             }  
  84.             url += param.toString();  
  85.         }  
  86.   
  87.         String body = null;  
  88.         CloseableHttpResponse response = null;  
  89.         try {  
  90.             httpClient = HttpClients.custom()  
  91.                     .setDefaultRequestConfig(REQUEST_CONFIG)  
  92.                     .build();  
  93.             HttpGet httpGet = new HttpGet(url);  
  94.             response = httpClient.execute(httpGet);  
  95.             body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);  
  96.         } catch (Exception e) {  
  97.             e.printStackTrace();  
  98.         } finally {  
  99.             if (response != null) {  
  100.                 try {  
  101.                     response.close();  
  102.                 } catch (IOException e) {  
  103.                     e.printStackTrace();  
  104.                 }  
  105.             }  
  106.   
  107.             if (httpClient != null) {  
  108.                 try {  
  109.                     httpClient.close();  
  110.                 } catch (IOException e) {  
  111.                     e.printStackTrace();  
  112.                 }  
  113.             }  
  114.         }  
  115.         return body;  
  116.     }  
  117.   
  118.     /** 
  119.      * @description 功能描述: get 请求 
  120.      * @param url 请求地址 
  121.      * @return 请求失败返回null 
  122.      */  
  123.     public static String get(String url) {  
  124.         return get(url, null);  
  125.     }  
  126.   
  127.     /** 
  128.      * @description 功能描述: get 请求 
  129.      * @param url 请求地址 
  130.      * @param params 参数 
  131.      * @return 请求失败返回null 
  132.      */  
  133.     public static String get(String url, Map<String, String> params) {  
  134.         return get(url, params, null);  
  135.     }  
  136.   
  137.     /** 
  138.      * @description 功能描述: post 请求 
  139.      * @param url 请求地址 
  140.      * @param params 参数 
  141.      * @return 请求失败返回null 
  142.      */  
  143.     public static String post(String url, Map<String, String> params) {  
  144.         CloseableHttpClient httpClient = null;  
  145.         HttpPost httpPost = new HttpPost(url);  
  146.         List<NameValuePair> nameValuePairs = new ArrayList<>();  
  147.         if (params != null && !params.isEmpty()) {  
  148.             for (Entry<String, String> entry : params.entrySet()) {  
  149.                 nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));  
  150.             }  
  151.         }  
  152.   
  153.         String body = null;  
  154.         CloseableHttpResponse response = null;  
  155.         try {  
  156.             httpClient = HttpClients.custom()  
  157.                     .setDefaultRequestConfig(REQUEST_CONFIG)  
  158.                     .build();  
  159.             httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));  
  160.             response = httpClient.execute(httpPost);  
  161.             body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);  
  162.         } catch (Exception e) {  
  163.             e.printStackTrace();  
  164.         } finally {  
  165.             if (response != null) {  
  166.                 try {  
  167.                     response.close();  
  168.                 } catch (IOException e) {  
  169.                     e.printStackTrace();  
  170.                 }  
  171.             }  
  172.   
  173.             if (httpClient != null) {  
  174.                 try {  
  175.                     httpClient.close();  
  176.                 } catch (IOException e) {  
  177.                     e.printStackTrace();  
  178.                 }  
  179.             }  
  180.         }  
  181.         return body;  
  182.     }  
  183.   
  184.     /** 
  185.      * @description 功能描述: post 请求 
  186.      * @param url 请求地址 
  187.      * @param s 参数xml 
  188.      * @return 请求失败返回null 
  189.      */  
  190.     public static String post(String url, String s) {  
  191.         CloseableHttpClient httpClient = null;  
  192.         HttpPost httpPost = new HttpPost(url);  
  193.         String body = null;  
  194.         CloseableHttpResponse response = null;  
  195.         try {  
  196.             httpClient = HttpClients.custom()  
  197.                     .setDefaultRequestConfig(REQUEST_CONFIG)  
  198.                     .build();  
  199.             httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));  
  200.             response = httpClient.execute(httpPost);  
  201.             body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);  
  202.         } catch (Exception e) {  
  203.             e.printStackTrace();  
  204.         } finally {  
  205.             if (response != null) {  
  206.                 try {  
  207.                     response.close();  
  208.                 } catch (IOException e) {  
  209.                     e.printStackTrace();  
  210.                 }  
  211.             }  
  212.   
  213.             if (httpClient != null) {  
  214.                 try {  
  215.                     httpClient.close();  
  216.                 } catch (IOException e) {  
  217.                     e.printStackTrace();  
  218.                 }  
  219.             }  
  220.         }  
  221.         return body;  
  222.     }  
  223.   
  224.     /** 
  225.      * @description 功能描述: post https请求,服务器双向证书验证 
  226.      * @param url 请求地址 
  227.      * @param params 参数 
  228.      * @return 请求失败返回null 
  229.      */  
  230.      public static String posts(String url, Map<String, String> params) {  
  231.         CloseableHttpClient httpClient = null;  
  232.         HttpPost httpPost = new HttpPost(url);  
  233.         List<NameValuePair> nameValuePairs = new ArrayList<>();  
  234.         if (params != null && !params.isEmpty()) {  
  235.             for (Entry<String, String> entry : params.entrySet()) {  
  236.                 nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));  
  237.             }  
  238.         }  
  239.   
  240.         String body = null;  
  241.         CloseableHttpResponse response = null;  
  242.         try {  
  243.             httpClient = HttpClients.custom()  
  244.                     .setDefaultRequestConfig(REQUEST_CONFIG)  
  245.                     .setSSLSocketFactory(getSSLConnectionSocket())  
  246.                     .build();  
  247.             httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));  
  248.             response = httpClient.execute(httpPost);  
  249.             body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);  
  250.         } catch (Exception e) {  
  251.             e.printStackTrace();  
  252.         } finally {  
  253.             if (response != null) {  
  254.                 try {  
  255.                     response.close();  
  256.                 } catch (IOException e) {  
  257.                     e.printStackTrace();  
  258.                 }  
  259.             }  
  260.   
  261.             if (httpClient != null) {  
  262.                 try {  
  263.                     httpClient.close();  
  264.                 } catch (IOException e) {  
  265.                     e.printStackTrace();  
  266.                 }  
  267.             }  
  268.         }  
  269.         return body;  
  270.     }  
  271.       
  272.     /** 
  273.      * @description 功能描述: post https请求,服务器双向证书验证 
  274.      * @param url 请求地址 
  275.      * @param s 参数xml 
  276.      * @return 请求失败返回null 
  277.      */  
  278.     public static String posts(String url, String s) {  
  279.         CloseableHttpClient httpClient = null;  
  280.         HttpPost httpPost = new HttpPost(url);  
  281.         String body = null;  
  282.         CloseableHttpResponse response = null;  
  283.         try {  
  284.             httpClient = HttpClients.custom()  
  285.                     .setDefaultRequestConfig(REQUEST_CONFIG)  
  286.                     .setSSLSocketFactory(getSSLConnectionSocket())  
  287.                     .build();  
  288.             httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));   
  289.             response = httpClient.execute(httpPost);  
  290.             body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);  
  291.         } catch (Exception e) {  
  292.             e.printStackTrace();  
  293.         } finally {  
  294.             if (response != null) {  
  295.                 try {  
  296.                     response.close();  
  297.                 } catch (IOException e) {  
  298.                     e.printStackTrace();  
  299.                 }  
  300.             }  
  301.   
  302.             if (httpClient != null) {  
  303.                 try {  
  304.                     httpClient.close();  
  305.                 } catch (IOException e) {  
  306.                     e.printStackTrace();  
  307.                 }  
  308.             }  
  309.         }  
  310.         return body;  
  311.     }  
  312.   
  313.     //获取ssl connection链接  
  314.     private static SSLConnectionSocketFactory getSSLConnectionSocket() {  
  315.         return new SSLConnectionSocketFactory(wx_ssl_context, new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}, null,  
  316.                 SSLConnectionSocketFactory.getDefaultHostnameVerifier());  
  317.     }  
  318. }  

 

 

     二、com.ning异步请求async-http-client

    1、引入文件

 

    

[java] view plain copy
 
  1. <dependency>  
  2.             <groupId>com.ning</groupId>  
  3.             <artifactId>async-http-client</artifactId>  
  4.             <version>1.9.40</version>  
  5.         </dependency>  

 

 

 

    2、http和https的方法封装

 

    涉及常用的post和get的请求,https的ssl双向证书验证。

 

[java] view plain copy
 
  1. import java.security.KeyStore;  
  2. import java.security.SecureRandom;  
  3. import java.util.Map;  
  4. import java.util.Set;  
  5. import java.util.concurrent.Future;  
  6.   
  7. import javax.net.ssl.KeyManagerFactory;  
  8. import javax.net.ssl.SSLContext;  
  9.   
  10. import org.springframework.core.io.ClassPathResource;  
  11. import org.springframework.core.io.Resource;  
  12.   
  13. import com.ning.http.client.AsyncHttpClient;  
  14. import com.ning.http.client.AsyncHttpClientConfig;  
  15. import com.ning.http.client.Response;  
  16.   
  17. /** 
  18.  * 创建时间:2016年11月8日 下午5:16:32 
  19.  *  
  20.  * @author andy 
  21.  * @version 2.2 
  22.  */  
  23. public class HttpKit {  
  24.       
  25.     private static final String DEFAULT_CHARSET = "UTF-8";  
  26.       
  27.     private static final int CONNECT_TIME_OUT = 5000; //链接超时时间3秒  
  28.   
  29.     private static SSLContext wx_ssl_context = null; //微信支付ssl证书  
  30.       
  31.     static{  
  32.           
  33.         Resource resource = new ClassPathResource("wx_apiclient_cert.p12"); //获取微信证书 或者直接从文件流读取  
  34.         char[] keyStorePassword = ConfigUtil.getProperty("wx.mchid").toCharArray(); //证书密码  
  35.         try {  
  36.             KeyStore keystore = KeyStore.getInstance("PKCS12");  
  37.             keystore.load(resource.getInputStream(), keyStorePassword);  
  38.             KeyManagerFactory keyManagerFactory = KeyManagerFactory  
  39.                     .getInstance(KeyManagerFactory.getDefaultAlgorithm());  
  40.             keyManagerFactory.init(keystore, keyStorePassword);  
  41.             SSLContext wx_ssl_context = SSLContext.getInstance("TLS");  
  42.             wx_ssl_context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());  
  43.         } catch (Exception e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47.   
  48.     /** 
  49.      * @description 功能描述: get 请求 
  50.      * @param url 请求地址 
  51.      * @param params 参数 
  52.      * @param headers headers参数 
  53.      * @return 请求失败返回null 
  54.      */  
  55.     public static String get(String url, Map<String, String> params, Map<String, String> headers) {  
  56.         AsyncHttpClient http = new AsyncHttpClient(new AsyncHttpClientConfig.Builder()  
  57.                 .setConnectTimeout(CONNECT_TIME_OUT).build());  
  58.         AsyncHttpClient.BoundRequestBuilder builder = http.prepareGet(url);  
  59.         builder.setBodyEncoding(DEFAULT_CHARSET);  
  60.         if (params != null && !params.isEmpty()) {  
  61.             Set<String> keys = params.keySet();  
  62.             for (String key : keys) {  
  63.                 builder.addQueryParam(key, params.get(key));  
  64.             }  
  65.         }  
  66.   
  67.         if (headers != null && !headers.isEmpty()) {  
  68.             Set<String> keys = headers.keySet();  
  69.             for (String key : keys) {  
  70.                 builder.addHeader(key, params.get(key));  
  71.             }  
  72.         }  
  73.         Future<Response> f = builder.execute();  
  74.         String body = null;  
  75.         try {  
  76.             body = f.get().getResponseBody(DEFAULT_CHARSET);  
  77.         } catch (Exception e) {  
  78.             e.printStackTrace();  
  79.         }  
  80.         http.close();  
  81.         return body;  
  82.     }  
  83.   
  84.     /** 
  85.      * @description 功能描述: get 请求 
  86.      * @param url 请求地址 
  87.      * @return 请求失败返回null 
  88.      */  
  89.     public static String get(String url) {  
  90.         return get(url, null);  
  91.     }  
  92.   
  93.     /** 
  94.      * @description 功能描述: get 请求 
  95.      * @param url 请求地址 
  96.      * @param params 参数 
  97.      * @return 请求失败返回null 
  98.      */  
  99.     public static String get(String url, Map<String, String> params) {  
  100.         return get(url, params, null);  
  101.     }  
  102.   
  103.     /** 
  104.      * @description 功能描述: post 请求 
  105.      * @param url 请求地址 
  106.      * @param params 参数 
  107.      * @return 请求失败返回null 
  108.      */  
  109.     public static String post(String url, Map<String, String> params) {  
  110.         AsyncHttpClient http = new AsyncHttpClient(new AsyncHttpClientConfig.Builder()  
  111.                 .setConnectTimeout(CONNECT_TIME_OUT).build());  
  112.         AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);  
  113.         builder.setBodyEncoding(DEFAULT_CHARSET);  
  114.         if (params != null && !params.isEmpty()) {  
  115.             Set<String> keys = params.keySet();  
  116.             for (String key : keys) {  
  117.                 builder.addQueryParam(key, params.get(key));  
  118.             }  
  119.         }  
  120.         Future<Response> f = builder.execute();  
  121.         String body = null;  
  122.         try {  
  123.             body = f.get().getResponseBody(DEFAULT_CHARSET);  
  124.         } catch (Exception e) {  
  125.             e.printStackTrace();  
  126.         }  
  127.         http.close();  
  128.         return body;  
  129.     }  
  130.   
  131.     /** 
  132.      * @description 功能描述: post 请求 
  133.      * @param url 请求地址 
  134.      * @param s 参数xml 
  135.      * @return 请求失败返回null 
  136.      */  
  137.     public static String post(String url, String s) {  
  138.         AsyncHttpClient http = new AsyncHttpClient(new AsyncHttpClientConfig.Builder()  
  139.                 .setConnectTimeout(CONNECT_TIME_OUT).build());  
  140.         AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);  
  141.         builder.setBodyEncoding(DEFAULT_CHARSET);  
  142.         builder.setBody(s);  
  143.         Future<Response> f = builder.execute();  
  144.         String body = null;  
  145.         try {  
  146.             body = f.get().getResponseBody(DEFAULT_CHARSET);  
  147.         } catch (Exception e) {  
  148.             e.printStackTrace();  
  149.         }  
  150.         http.close();  
  151.         return body;  
  152.     }  
  153.   
  154.     /** 
  155.      * @description 功能描述: post https请求,服务器双向证书验证 
  156.      * @param url 请求地址 
  157.      * @param params 参数 
  158.      * @return 请求失败返回null 
  159.      */  
  160.     public static String posts(String url, Map<String, String> params){  
  161.   
  162.         AsyncHttpClient http = new AsyncHttpClient(  
  163.                 new AsyncHttpClientConfig.Builder()  
  164.                 .setConnectTimeout(CONNECT_TIME_OUT)  
  165.                 .setSSLContext(wx_ssl_context)  
  166.                 .build());  
  167.         AsyncHttpClient.BoundRequestBuilder bbuilder = http.preparePost(url);  
  168.         bbuilder.setBodyEncoding(DEFAULT_CHARSET);  
  169.         if (params != null && !params.isEmpty()) {  
  170.             Set<String> keys = params.keySet();  
  171.             for (String key : keys) {  
  172.                 bbuilder.addQueryParam(key, params.get(key));  
  173.             }  
  174.         }  
  175.         Future<Response> f = bbuilder.execute();  
  176.         String body = null;  
  177.         try {  
  178.             body = f.get().getResponseBody(DEFAULT_CHARSET);  
  179.         } catch (Exception e) {  
  180.             e.printStackTrace();  
  181.         }  
  182.         http.close();  
  183.         return body;  
  184.     }  
  185.   
  186.     /** 
  187.      * @description 功能描述: post https请求,服务器双向证书验证 
  188.      * @param url 请求地址 
  189.      * @param s 参数xml 
  190.      * @return 请求失败返回null 
  191.      */  
  192.     public static String posts(String url, String s) {  
  193.         AsyncHttpClient http = new AsyncHttpClient(  
  194.                 new AsyncHttpClientConfig.Builder()  
  195.                 .setConnectTimeout(CONNECT_TIME_OUT)  
  196.                 .setSSLContext(wx_ssl_context).build());  
  197.         AsyncHttpClient.BoundRequestBuilder builder = http.preparePost(url);  
  198.         builder.setBodyEncoding(DEFAULT_CHARSET);  
  199.         builder.setBody(s);  
  200.         Future<Response> f = builder.execute();  
  201.         String body = null;  
  202.         try {  
  203.             body = f.get().getResponseBody(DEFAULT_CHARSET);  
  204.         } catch (Exception e) {  
  205.             e.printStackTrace();  
  206.         }  
  207.         http.close();  
  208.         return body;  
  209.     }  
  210. }  



 

 

    三、测试

 

    相同结果下,对同一网络请求平均测试20次请求性能

         

   

    对于少量的网络请求来说httpclient和异步的async-http-client相差无几,甚至比异步还要快,但是在大量网络请求来说异步性能可能更高,但是上面需要优化如减少链接创建、设置超时时间、设置重试次数等等。

 

posted @ 2018-03-27 10:09  这个名字想了很久~  阅读(6245)  评论(0编辑  收藏  举报