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

论坛 期权论坛 脚本     
匿名技术用户   2021-1-3 23:37   50   0

原文: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、引入文件

  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双向证书验证。

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

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

1、引入文件

  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双向证书验证。

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



三、测试

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

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

转载于:https://www.cnblogs.com/shihaiming/p/8655939.html

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP