基于springboot的RestTemplate、okhttp和HttpClient对比

快来打我* 2022-11-30 05:55 291阅读 0赞

1、HttpClient:代码复杂,还得操心资源回收等。代码很复杂,冗余代码多,不建议直接使用。

  1. @RequestMapping("/doPostGetJson")
  2. public String doPostGetJson() throws ParseException {
  3. //此处将要发送的数据转换为json格式字符串
  4. String jsonText = "{id:1}";
  5. JSONObject json = (JSONObject) JSONObject.parse(jsonText);
  6. JSONObject sr = this.doPost(json);
  7. System.out.println("返回参数:" + sr);
  8. return sr.toString();
  9. }
  10. public static JSONObject doPost(JSONObject date) {
  11. HttpClient client = HttpClients.createDefault();
  12. // 要调用的接口方法
  13. String url = "http://192.168.1.101:8080/getJson";
  14. HttpPost post = new HttpPost(url);
  15. JSONObject jsonObject = null;
  16. try {
  17. StringEntity s = new StringEntity(date.toString());
  18. s.setContentEncoding("UTF-8");
  19. s.setContentType("application/json");
  20. post.setEntity(s);
  21. post.addHeader("content-type", "text/xml");
  22. HttpResponse res = client.execute(post);
  23. String response1 = EntityUtils.toString(res.getEntity());
  24. System.out.println(response1);
  25. if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  26. String result = EntityUtils.toString(res.getEntity());// 返回json格式:
  27. jsonObject = JSONObject.parseObject(result);
  28. }
  29. } catch (Exception e) {
  30. throw new RuntimeException(e);
  31. }
  32. return jsonObject;
  33. }

2、RestTemplate: 是 Spring 提供的用于访问Rest服务的客户端, RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

引入jar包:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>

添加初始化配置(也可以不配,有默认的)—注意RestTemplate只有初始化配置,没有什么连接池

  1. package com.itunion.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.http.client.ClientHttpRequestFactory;
  5. import org.springframework.http.client.SimpleClientHttpRequestFactory;
  6. import org.springframework.web.client.RestTemplate;
  7. @Configuration
  8. public class ApiConfig {
  9. @Bean
  10. public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
  11. return new RestTemplate(factory);
  12. }
  13. @Bean
  14. public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
  15. SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();//默认的是JDK提供http连接,需要的话可以//通过setRequestFactory方法替换为例如Apache HttpComponents、Netty或//OkHttp等其它HTTP library。
  16. factory.setReadTimeout(5000);//单位为ms
  17. factory.setConnectTimeout(5000);//单位为ms
  18. return factory;
  19. }
  20. }

1)get请求(不带参的即把参数取消即可)

  1. // 1-getForObject()
  2. User user1 = this.restTemplate.getForObject(uri, User.class);
  3. // 2-getForEntity()
  4. ResponseEntity<User> responseEntity1 = this.restTemplate.getForEntity(uri, User.class);
  5. HttpStatus statusCode = responseEntity1.getStatusCode();
  6. HttpHeaders header = responseEntity1.getHeaders();
  7. User user2 = responseEntity1.getBody();
  8. // 3-exchange()
  9. RequestEntity requestEntity = RequestEntity.get(new URI(uri)).build();
  10. ResponseEntity<User> responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);
  11. User user3 = responseEntity2.getBody();

方式一:

  1. Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/{1}/{2}"
  2. , Notice.class,1,5);

方式二:

  1. Map<String,String> map = new HashMap();
  2. map.put("start","1");
  3. map.put("page","5");
  4. Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/"
  5. , Notice.class,map);

2)post请求:

  1. // 1-postForObject()
  2. User user1 = this.restTemplate.postForObject(uri, user, User.class);
  3. // 2-postForEntity()
  4. ResponseEntity<User> responseEntity1 = this.restTemplate.postForEntity(uri, user, User.class);
  5. // 3-exchange()
  6. RequestEntity<User> requestEntity = RequestEntity.post(new URI(uri)).body(user);
  7. ResponseEntity<User> responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);

方式一:

  1. String url = "http://demo/api/book/";
  2. HttpHeaders headers = new HttpHeaders();
  3. MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
  4. headers.setContentType(type);
  5. String requestJson = "{...}";
  6. HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
  7. String result = restTemplate.postForObject(url, entity, String.class);
  8. System.out.println(result);

方式二:

  1. @Test
  2. public void rtPostObject(){
  3. RestTemplate restTemplate = new RestTemplate();
  4. String url = "http://47.xxx.xxx.96/register/checkEmail";
  5. HttpHeaders headers = new HttpHeaders();
  6. headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
  7. MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
  8. map.add("email", "844072586@qq.com");
  9. HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
  10. ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );
  11. System.out.println(response.getBody());
  12. }

其它:还支持上传和下载功能;

3、okhttp:OkHttp是一个高效的HTTP客户端,允许所有同一个主机地址的请求共享同一个socket连接;连接池减少请求延时;透明的GZIP压缩减少响应数据的大小;缓存响应内容,避免一些完全重复的请求

当网络出现问题的时候OkHttp依然坚守自己的职责,它会自动恢复一般的连接问题,如果你的服务有多个IP地址,当第一个IP请求失败时,OkHttp会交替尝试你配置的其他IP,OkHttp使用现代TLS技术(SNI, ALPN)初始化新的连接,当握手失败时会回退到TLS 1.0。

1)使用:它的请求/响应 API 使用构造器模式builders来设计,它支持阻塞式的同步请求和带回调的异步请求。

引入jar包:

  1. <dependency>
  2. <groupId>com.squareup.okhttp3</groupId>
  3. <artifactId>okhttp</artifactId>
  4. <version>3.10.0</version>
  5. </dependency>

2)配置文件:

  1. import okhttp3.ConnectionPool;
  2. import okhttp3.OkHttpClient;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import javax.net.ssl.SSLContext;
  6. import javax.net.ssl.SSLSocketFactory;
  7. import javax.net.ssl.TrustManager;
  8. import javax.net.ssl.X509TrustManager;
  9. import java.security.KeyManagementException;
  10. import java.security.NoSuchAlgorithmException;
  11. import java.security.SecureRandom;
  12. import java.security.cert.CertificateException;
  13. import java.security.cert.X509Certificate;
  14. import java.util.concurrent.TimeUnit;
  15. @Configuration
  16. public class OkHttpConfiguration {
  17. @Bean
  18. public OkHttpClient okHttpClient() {
  19. return new OkHttpClient.Builder()
  20. //.sslSocketFactory(sslSocketFactory(), x509TrustManager())
  21. .retryOnConnectionFailure(false)
  22. .connectionPool(pool())
  23. .connectTimeout(30, TimeUnit.SECONDS)
  24. .readTimeout(30, TimeUnit.SECONDS)
  25. .writeTimeout(30,TimeUnit.SECONDS)
  26. .build();
  27. }
  28. @Bean
  29. public X509TrustManager x509TrustManager() {
  30. return new X509TrustManager() {
  31. @Override
  32. public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
  33. }
  34. @Override
  35. public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
  36. }
  37. @Override
  38. public X509Certificate[] getAcceptedIssuers() {
  39. return new X509Certificate[0];
  40. }
  41. };
  42. }
  43. @Bean
  44. public SSLSocketFactory sslSocketFactory() {
  45. try {
  46. //信任任何链接
  47. SSLContext sslContext = SSLContext.getInstance("TLS");
  48. sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
  49. return sslContext.getSocketFactory();
  50. } catch (NoSuchAlgorithmException e) {
  51. e.printStackTrace();
  52. } catch (KeyManagementException e) {
  53. e.printStackTrace();
  54. }
  55. return null;
  56. }
  57. /**
  58. * Create a new connection pool with tuning parameters appropriate for a single-user application.
  59. * The tuning parameters in this pool are subject to change in future OkHttp releases. Currently
  60. */
  61. @Bean
  62. public ConnectionPool pool() {
  63. return new ConnectionPool(200, 5, TimeUnit.MINUTES);
  64. }
  65. }

3)util工具:

  1. import okhttp3.*;
  2. import org.apache.commons.lang3.exception.ExceptionUtils;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import java.io.File;
  6. import java.util.Iterator;
  7. import java.util.Map;
  8. public class OkHttpUtil{
  9. private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);
  10. private static OkHttpClient okHttpClient;
  11. @Autowired
  12. public OkHttpUtil(OkHttpClient okHttpClient) {
  13. OkHttpUtil.okHttpClient= okHttpClient;
  14. }
  15. /**
  16. * get
  17. * @param url 请求的url
  18. * @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
  19. * @return
  20. */
  21. public static String get(String url, Map<String, String> queries) {
  22. String responseBody = "";
  23. StringBuffer sb = new StringBuffer(url);
  24. if (queries != null && queries.keySet().size() > 0) {
  25. boolean firstFlag = true;
  26. Iterator iterator = queries.entrySet().iterator();
  27. while (iterator.hasNext()) {
  28. Map.Entry entry = (Map.Entry<String, String>) iterator.next();
  29. if (firstFlag) {
  30. sb.append("?" + entry.getKey() + "=" + entry.getValue());
  31. firstFlag = false;
  32. } else {
  33. sb.append("&" + entry.getKey() + "=" + entry.getValue());
  34. }
  35. }
  36. }
  37. Request request = new Request.Builder()
  38. .url(sb.toString())
  39. .build();
  40. Response response = null;
  41. try {
  42. response = okHttpClient.newCall(request).execute();
  43. int status = response.code();
  44. if (response.isSuccessful()) {
  45. return response.body().string();
  46. }
  47. } catch (Exception e) {
  48. logger.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
  49. } finally {
  50. if (response != null) {
  51. response.close();
  52. }
  53. }
  54. return responseBody;
  55. }
  56. /**
  57. * post
  58. *
  59. * @param url 请求的url
  60. * @param params post form 提交的参数
  61. * @return
  62. */
  63. public static String post(String url, Map<String, String> params) {
  64. String responseBody = "";
  65. FormBody.Builder builder = new FormBody.Builder();
  66. //添加参数
  67. if (params != null && params.keySet().size() > 0) {
  68. for (String key : params.keySet()) {
  69. builder.add(key, params.get(key));
  70. }
  71. }
  72. Request request = new Request.Builder()
  73. .url(url)
  74. .post(builder.build())
  75. .build();
  76. Response response = null;
  77. try {
  78. response = okHttpClient.newCall(request).execute();
  79. int status = response.code();
  80. if (response.isSuccessful()) {
  81. return response.body().string();
  82. }
  83. } catch (Exception e) {
  84. logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
  85. } finally {
  86. if (response != null) {
  87. response.close();
  88. }
  89. }
  90. return responseBody;
  91. }
  92. /**
  93. * get
  94. * @param url 请求的url
  95. * @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
  96. * @return
  97. */
  98. public static String getForHeader(String url, Map<String, String> queries) {
  99. String responseBody = "";
  100. StringBuffer sb = new StringBuffer(url);
  101. if (queries != null && queries.keySet().size() > 0) {
  102. boolean firstFlag = true;
  103. Iterator iterator = queries.entrySet().iterator();
  104. while (iterator.hasNext()) {
  105. Map.Entry entry = (Map.Entry<String, String>) iterator.next();
  106. if (firstFlag) {
  107. sb.append("?" + entry.getKey() + "=" + entry.getValue());
  108. firstFlag = false;
  109. } else {
  110. sb.append("&" + entry.getKey() + "=" + entry.getValue());
  111. }
  112. }
  113. }
  114. Request request = new Request.Builder()
  115. .addHeader("key", "value")
  116. .url(sb.toString())
  117. .build();
  118. Response response = null;
  119. try {
  120. response = okHttpClient.newCall(request).execute();
  121. int status = response.code();
  122. if (response.isSuccessful()) {
  123. return response.body().string();
  124. }
  125. } catch (Exception e) {
  126. logger.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
  127. } finally {
  128. if (response != null) {
  129. response.close();
  130. }
  131. }
  132. return responseBody;
  133. }
  134. /**
  135. * Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
  136. * 参数一:请求Url
  137. * 参数二:请求的JSON
  138. * 参数三:请求回调
  139. */
  140. public static String postJsonParams(String url, String jsonParams) {
  141. String responseBody = "";
  142. RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
  143. Request request = new Request.Builder()
  144. .url(url)
  145. .post(requestBody)
  146. .build();
  147. Response response = null;
  148. try {
  149. response = okHttpClient.newCall(request).execute();
  150. int status = response.code();
  151. if (response.isSuccessful()) {
  152. return response.body().string();
  153. }
  154. } catch (Exception e) {
  155. logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
  156. } finally {
  157. if (response != null) {
  158. response.close();
  159. }
  160. }
  161. return responseBody;
  162. }
  163. /**
  164. * Post请求发送xml数据....
  165. * 参数一:请求Url
  166. * 参数二:请求的xmlString
  167. * 参数三:请求回调
  168. */
  169. public static String postXmlParams(String url, String xml) {
  170. String responseBody = "";
  171. RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
  172. Request request = new Request.Builder()
  173. .url(url)
  174. .post(requestBody)
  175. .build();
  176. Response response = null;
  177. try {
  178. response = okHttpClient.newCall(request).execute();
  179. int status = response.code();
  180. if (response.isSuccessful()) {
  181. return response.body().string();
  182. }
  183. } catch (Exception e) {
  184. logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
  185. } finally {
  186. if (response != null) {
  187. response.close();
  188. }
  189. }
  190. return responseBody;
  191. }
  192. }

发表评论

表情:
评论列表 (有 0 条评论,291人围观)

还没有评论,来说两句吧...

相关阅读