原文: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. [c++,bson] linux 使用 BSON 编程[www]

    [c++,bson] linux 使用 BSON 编程 http://blog.chinaunix.net/uid-28595538-id-4987410.html 1.js db=db.getSib ...

  2. C#使用Linq To XML读取XML,Linq生成XML,Linq创建带属性或带节点XML

    using System; using System.Linq; using System.Xml.Linq; namespace Sample2 { class Program { static v ...

  3. 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6154 CaoHaha's staff 思维

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6154 题意:在笛卡尔坐标系下,画一个面积至少为  n 的简单多边形,每次只能画一条边或者一个格子的对角 ...

  4. HTML5 一篇就够的中文教程

    HTML5 是近十年来 Web 开发标准最巨大的飞跃.HTML5 并非仅仅用来表示 Web 内容,它将 Web 带入一个成熟的应用平台,在 HTML5 平台上,视频.音频.图象.动画,以及同电脑的交互 ...

  5. axios使用

    axios 基于promise用于浏览器和node.js的http客户端 特点 支持浏览器和node.js 支持promise 能拦截请求和响应 能转换请求和响应数据 能取消请求 自动转换JSON数据 ...

  6. aspxpivotgrid排序

    protected virtual void SetSortBySummary() { foreach (PivotGridField field in grid.Fields) { if (fiel ...

  7. English——Unit 2

    radiant radiate radical ideal ideology identical identification identify identity journal jounalist ...

  8. php设计模式五----适配器模式

    1.简介 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能. 意图:将一个类的接口转换成客户希望的另外一个接口 ...

  9. 字符串截取,SubString

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAk8AAACYCAIAAAByAZqHAAAYgklEQVR4nO2dL28ku5qHTS4ctuTSQf ...

  10. POJ 1733 Parity game(带权并查集)

    题目链接:http://poj.org/problem?id=1733 题目大意:给你m条信息,每条信息告诉你区间l~r的1的个数是奇数还是偶数,如果后面出现信息跟前面矛盾则这条信息是错误的,问在第一 ...