一、背景介绍

 在微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。这里介绍的是RestTemplate。RestTemplate底层用还是HttpClient,对其做了封装,使用起来更简单。

1、什么是RestTemplate?

RestTemplate是Spring提供的用于访问Rest服务的客户端,
RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求,
可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。
ClientHttpRequestFactory接口主要提供了两种实现方式
1、一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。
2、一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。

其实spring并没有真正的去实现底层的http请求(3次握手),而是集成了别的http请求,spring只是在原有的各种http请求进行了规范标准,让开发者更加简单易用,底层默认用的是jdk的http请求。

2、RestTemplate的优缺点:

优点:连接池、超时时间设置、支持异步、请求和响应的编解码
缺点:依赖别的spring版块、参数传递不灵活

RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的HttpConnection,默认超时为-1

@Autowired
RestTemplate simpleRestTemplate;
@Autowired
RestTemplate restTemplate;

二、配置RestTemplate

1、引入依赖

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.6</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、连接池配置

#最大连接数
http.maxTotal: 100
#并发数
http.defaultMaxPerRoute: 20
#创建连接的最长时间
http.connectTimeout: 1000
#从连接池中获取到连接的最长时间
http.connectionRequestTimeout: 500
#数据传输的最长时间
http.socketTimeout: 10000
#提交请求前测试连接是否可用
http.staleConnectionCheckEnabled: true
#可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
http.validateAfterInactivity: 3000000

3、初始化连接池

package com.example.demo.config;import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig {@Value("${http.maxTotal}")private Integer maxTotal;@Value("${http.defaultMaxPerRoute}")private Integer defaultMaxPerRoute;@Value("${http.connectTimeout}")private Integer connectTimeout;@Value("${http.connectionRequestTimeout}")private Integer connectionRequestTimeout;@Value("${http.socketTimeout}")private Integer socketTimeout;@Value("${http.staleConnectionCheckEnabled}")private boolean staleConnectionCheckEnabled;@Value("${http.validateAfterInactivity}")private Integer validateAfterInactivity;@Beanpublic RestTemplate restTemplate() {return new RestTemplate(httpRequestFactory());}@Beanpublic ClientHttpRequestFactory httpRequestFactory() {return new HttpComponentsClientHttpRequestFactory(httpClient());}@Beanpublic HttpClient httpClient() {Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", SSLConnectionSocketFactory.getSocketFactory()).build();PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);connectionManager.setMaxTotal(maxTotal); // 最大连接数connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);    //单个路由最大连接数connectionManager.setValidateAfterInactivity(validateAfterInactivity); // 最大空间时间RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)        //服务器返回数据(response)的时间,超过抛出read timeout.setConnectTimeout(connectTimeout)      //连接上服务器(握手成功)的时间,超出抛出connect timeout.setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // 提交前检测是否可用.setConnectionRequestTimeout(connectionRequestTimeout)//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                .build();return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();}}

4、使用示例

RestTemplate是对HttpCilent的封装,所以,依HttpCilent然可以继续使用HttpCilent。看下两者的区别

HttpCilent:

  @RequestMapping("/testHttpClient")@ResponseBodypublic Object getUser(String msg) throws IOException {CloseableHttpClient closeableHttpClient = HttpClients.createDefault();HttpGet get = new HttpGet("http://192.168.1.100:8080/User/getAllUser");CloseableHttpResponse response = closeableHttpClient.execute(get);return EntityUtils.toString(response.getEntity(), "utf-8");}

RestTemplate:

   @RequestMapping("/testRestTemplate")@ResponseBodypublic Object testRestTemplate() throws IOException {ResponseEntity result= restTemplate.getForEntity("http://192.168.1.100:8080/User/getAllUser",ResponseEntity.class);return result.getBody();}

RestTemplate更简洁了。

三、RestTemplate常用方法

1、getForEntity

getForEntity方法的返回值是一个ResponseEntity<T>ResponseEntity<T>是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。比如下面一个例子:

@RequestMapping("/sayhello")
public String sayHello() {ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={1}", String.class, "张三");return responseEntity.getBody();
}
@RequestMapping("/sayhello2")
public String sayHello2() {Map<String, String> map = new HashMap<>();map.put("name", "李四");ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map);return responseEntity.getBody();
}

2、getForObject

getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject,举一个简单的例子,如下:

@RequestMapping("/book2")
public Book book2() {Book book = restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class);return book;
}

3、postForEntity

@RequestMapping("/book3")
public Book book3() {Book book = new Book();book.setName("红楼梦");ResponseEntity<Book> responseEntity = restTemplate.postForEntity("http://HELLO-SERVICE/getbook2", book, Book.class);return responseEntity.getBody();
}

  • 方法的第一参数表示要调用的服务的地址
  • 方法的第二个参数表示上传的参数
  • 方法的第三个参数表示返回的消息体的数据类型

4、postForObject

如果你只关注,返回的消息体,可以直接使用postForObject。用法和getForObject一致。

5、postForLocation

postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数基本一致,只不过该方法的返回值为Uri,这个只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。

6、PUT请求

在RestTemplate中,PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForEntity方法的参数基本一致,只是put方法没有返回值而已。举一个简单的例子,如下:

@RequestMapping("/put")
public void put() {Book book = new Book();book.setName("红楼梦");restTemplate.put("http://HELLO-SERVICE/getbook3/{1}", book, 99);
}

7、DELETE请求

delete请求我们可以通过delete方法调用来实现,如下例子:

@RequestMapping("/delete")
public void delete() {restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
}

转载于:https://www.cnblogs.com/wangzhuxing/p/10200180.html

springboot系列十二、springboot集成RestTemplate及常见用法相关推荐

  1. SpringBoot系列课程(二)-SpringBoot整合MyBatis

    1.SpringBoot和MyBatis整合 1.2. 准备数据 SET FOREIGN_KEY_CHECKS=0;-- ---------------------------- -- Table s ...

  2. SpringBoot实战(十二)之集成kisso

    关于kisso介绍,大家可以参考官方文档或者是我的博客:https://www.cnblogs.com/youcong/p/9794735.html 一.导入maven依赖 xsi:schemaLoc ...

  3. springboot系列(十二):如何实现邮件发送提醒,你一定得会(准备篇)

  4. SpringBoot系列十:SpringBoot整合Redis

    From: https://www.cnblogs.com/leeSmall/p/8728231.html 声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:Sprin ...

  5. 《SpringBoot系列十六》条件装配时ConfigurationCondition和Condition有什么区别?什么时候用ConfigurationCondition?

    一.前言 针对条件装配我们讨论了如下内容: <SpringBoot系列十一>:精讲如何使用@Conditional系列注解做条件装配 <SpringBoot系列十二>:如何自定 ...

  6. Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】

    2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...

  7. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  8. springboot系列六、springboot配置错误页面及全局异常

    springboot系列六.springboot配置错误页面及全局异常 参考文章: (1)springboot系列六.springboot配置错误页面及全局异常 (2)https://www.cnbl ...

  9. SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)

    SpringBoot系列五:SpringBoot错误处理(数据验证.处理错误页.全局异常) 参考文章: (1)SpringBoot系列五:SpringBoot错误处理(数据验证.处理错误页.全局异常) ...

最新文章

  1. python杨辉三角居中center_python经典---杨辉三角(两种方法)
  2. 开启及关闭go mod
  3. Dapr + .NET 实战(四)发布和订阅
  4. 在windows下安装Redis
  5. 架构设计-数据访问层简述
  6. 唯有拼搏不负君(送年轻人8句话)
  7. File类和时间类的两道综合练习
  8. 31线性空间05——列空间和零空间、维数
  9. VC++ IE缓存管理研究
  10. 怎么获取jquery版本_获取jQuery版本
  11. 怎么把ide改成ahci_Win10系统无需重装,硬盘IDE改为AHCI模式的方法
  12. python绘制隐含波动率曲面_隐含波动率曲面
  13. 【软件质量】-01-缺陷严重等级定义
  14. 组装一台计算机的配置,要不要自己动手组装一台电脑?一文告诉你答案!
  15. Linux 3.10内核锁瓶颈描述以及解决-overlayfs的性能缺陷
  16. 风热感冒,风寒感冒,病毒性感冒,细菌性感冒
  17. html5城堡防御游戏《小英雄呼呼》截图
  18. 全新java架构技术框架Quarkus实战神仙文档
  19. 【(高职专科组)第十一届蓝桥杯省模拟赛答案】小明非常不喜欢数字 2,包括那些数位上包含数字 2 的数。如果一个数的数位不包含数字 2,小明将它称为洁净数。
  20. 21.2.22 T2 多米诺骨牌 真·详解

热门文章

  1. 自己定义View学习之12/7(进度条之混合模式)
  2. Android Support Annotations
  3. SPF,DSPF,RDPF,SPEF and SBPF.
  4. java 多线程——一个定时调度的例子
  5. 弄懂bind,apply和call的区别
  6. 计算机网络学习笔记(3. 计算机网络结构)
  7. Vue err:This dependency was not found
  8. 失败原因【object object】_使用前端框架Vue的原因!
  9. 为什么京东买手机不支持白条?
  10. 生活中有哪些越早明白越好的道理?