原文: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相差无几,甚至比异步还要快,但是在大量网络请求来说异步性能可能更高,但是上面需要优化如减少链接创建、设置超时时间、设置重试次数等等。

Http和Https网络同步请求httpclient和异步请求async-http-client的更多相关文章

  1. java判断请求是否ajax异步请求

    java判断请求是否ajax异步请求   解决方法: if (request.getHeader("x-requested-with") != null && re ...

  2. 普通B/S架构模式同步请求与AJAX异步请求区别(个人理解)

    在上次面试的时候有被问到过AJAX同步与异步之间的概念问题,之前没有涉及到异步与同步的知识,所以特意脑补了一下,不是很全面... 同步请求流程:提交请求(POST/GET表单相似的提交操作)---服务 ...

  3. .Net core webapi使用httpClient发送异步请求遇到TaskCanceledException: A task was canceled

    前言:本人最近较多使用.net core的项目,最近在使用httpClient发送请求的时候,遇到服务器处理时间较长时,就老是会报异常:TaskCanceledException: A task wa ...

  4. .Net WebRequest异步请求与WebClient异步请求

    很多情况下一般会使用同步方式发出请求,直到响应后再做后续的逻辑处理等,但有时候后续的逻辑处理不依赖于请求的结果或者是可以挂起等到响应后再处理,又或者是为了解决UI“假死”的现象,这时可以使用异步请求 ...

  5. 原生js--编码请求主体(异步请求)

    1.表单编码请求 需要对每个表单元素进行普通的URL编码,使用“=”把编码后的名字和值分开,并使用“&”分开名值对. 例如:a=b&c=d 表单数据编码的MIME类型:applicat ...

  6. Android okHttp网络请求之Get/Post请求

    前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...

  7. NSURLConnection同步与异步请求 问题

    NSURLConnection目前有两个异步请求方法,异步请求中其中一个是代理.一个同步方法.有前辈已经详细介绍,见:http://blog.csdn.net/xyz_lmn/article/deta ...

  8. 异步请求之ajax

    一.初识ajax 1.下载引入jQuery <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"& ...

  9. PHP异步请求之fsockopen()方法详解

    正常情况下,PHP执行的都是同步请求,代码自上而下依次执行,但有些场景如发送邮件.执行耗时任务等操作时就不适用于同步请求,只能使用异步处理请求. 场景要求: 客户端调用服务器a.php接口,需要执行一 ...

随机推荐

  1. 如何在苹果官网下载旧版本的Xcode

    如何在苹果官网下载旧版本的Xcode 前段时间XcodeGhost事件让很多应用中招,不乏一些知名的互联网公司开发的应用.事件的起因是开发者使用了非官方的Xcode,这些Xcode带有xcodegho ...

  2. [ python ] 类的组合

    首先,使用面向对象是一个人狗大战的实例: class Person: def __init__(self, name, hp, aggr, sex): self.name = name self.hp ...

  3. tab切换 jQuery

    $('p.guidan-load1').click(function(){ $("p.guidan-load1").removeClass("guidan-load12& ...

  4. linux命令(11):df命令

    1.查看磁盘空间和当前的磁盘数:df –lh或者df –i 2.显示指定类型磁盘:df -t ext4 3.列出各文件系统的i节点使用情况:df  -ia 4.列出文件系统的类型:df -T

  5. 【转载】Web开发技术发展历史-版本2

    原文在这里. Web开发的发展史 导读:Arunr 把过去 15 年以来,Web开发从最初的纯 HTML 到 CGI.PHP\JSP\ASP.Ajax.Rails.NodeJS 这个过程简要地进行了介 ...

  6. HTTP Status 500 - Handler processing failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment

    解决方案:修改catalina.sh 文件加上-Djava.awt.headless=true JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS -Djava.awt.hea ...

  7. JSTL 1.1与JSTL 1.2之间的区别?如何下载JSTL 1.2?

    JSTL 1.1与JSTL 1.2之间的区别?如何下载JSTL 1.2? JSTL 1.2中不要求standard.jar架包 您可以在Maven中央仓库中找到它们: http://repo2.mav ...

  8. es6字符串模板总结

    我们平时用原生js插入标签或者用node.js写数据库语言时候,经常需要大量的字符串进行转义,很容易出错,有了es6的字符串模板,就再也不用担心会出错了 1.模板中的变量写在${}中,${}中的值可以 ...

  9. JDBC浅析

    今天简单的说一下jdbc,本来这玩意儿也很简单. 大家只需要记住其中的几个重要的类就行了,它们都在sql包里.今天主要是拿mysql来连接.先看一下主要的几个类吧. 1.Conenction 2.St ...

  10. 从零开始做SSH项目(二)

    使用hibernate测试加载数据.删除数据和修改数据等功能时,针对的是与数据库表user对应的User. 为了简化对其他数据表对应的实体类的持久化操作,可以在项目中创建一个BaseHibernate ...