springboot系列十二、springboot集成RestTemplate及常见用法
一、背景介绍
在微服务都是以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可以配置连接池和证书等信息。
2、RestTemplate的优缺点:
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及常见用法相关推荐
- SpringBoot系列课程(二)-SpringBoot整合MyBatis
1.SpringBoot和MyBatis整合 1.2. 准备数据 SET FOREIGN_KEY_CHECKS=0;-- ---------------------------- -- Table s ...
- SpringBoot实战(十二)之集成kisso
关于kisso介绍,大家可以参考官方文档或者是我的博客:https://www.cnblogs.com/youcong/p/9794735.html 一.导入maven依赖 xsi:schemaLoc ...
- springboot系列(十二):如何实现邮件发送提醒,你一定得会(准备篇)
- SpringBoot系列十:SpringBoot整合Redis
From: https://www.cnblogs.com/leeSmall/p/8728231.html 声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:Sprin ...
- 《SpringBoot系列十六》条件装配时ConfigurationCondition和Condition有什么区别?什么时候用ConfigurationCondition?
一.前言 针对条件装配我们讨论了如下内容: <SpringBoot系列十一>:精讲如何使用@Conditional系列注解做条件装配 <SpringBoot系列十二>:如何自定 ...
- Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】
2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...
- Alamofire源码解读系列(十二)之请求(Request)
本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...
- springboot系列六、springboot配置错误页面及全局异常
springboot系列六.springboot配置错误页面及全局异常 参考文章: (1)springboot系列六.springboot配置错误页面及全局异常 (2)https://www.cnbl ...
- SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)
SpringBoot系列五:SpringBoot错误处理(数据验证.处理错误页.全局异常) 参考文章: (1)SpringBoot系列五:SpringBoot错误处理(数据验证.处理错误页.全局异常) ...
最新文章
- python杨辉三角居中center_python经典---杨辉三角(两种方法)
- 开启及关闭go mod
- Dapr + .NET 实战(四)发布和订阅
- 在windows下安装Redis
- 架构设计-数据访问层简述
- 唯有拼搏不负君(送年轻人8句话)
- File类和时间类的两道综合练习
- 31线性空间05——列空间和零空间、维数
- VC++ IE缓存管理研究
- 怎么获取jquery版本_获取jQuery版本
- 怎么把ide改成ahci_Win10系统无需重装,硬盘IDE改为AHCI模式的方法
- python绘制隐含波动率曲面_隐含波动率曲面
- 【软件质量】-01-缺陷严重等级定义
- 组装一台计算机的配置,要不要自己动手组装一台电脑?一文告诉你答案!
- Linux 3.10内核锁瓶颈描述以及解决-overlayfs的性能缺陷
- 风热感冒,风寒感冒,病毒性感冒,细菌性感冒
- html5城堡防御游戏《小英雄呼呼》截图
- 全新java架构技术框架Quarkus实战神仙文档
- 【(高职专科组)第十一届蓝桥杯省模拟赛答案】小明非常不喜欢数字 2,包括那些数位上包含数字 2 的数。如果一个数的数位不包含数字 2,小明将它称为洁净数。
- 21.2.22 T2 多米诺骨牌 真·详解
热门文章
- 自己定义View学习之12/7(进度条之混合模式)
- Android Support Annotations
- SPF,DSPF,RDPF,SPEF and SBPF.
- java 多线程——一个定时调度的例子
- 弄懂bind,apply和call的区别
- 计算机网络学习笔记(3. 计算机网络结构)
- Vue err:This dependency was not found
- 失败原因【object object】_使用前端框架Vue的原因!
- 为什么京东买手机不支持白条?
- 生活中有哪些越早明白越好的道理?