RestTemplate的一些坑和改造点
一、RestTemplate怎么引入和使用
在pom.xml文件中加入如下dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在项目的config文件夹下创建InitBeanConfig.java,添加如下代码:
1 @Bean
2 public RestTemplate getRestTemplate() {
3 return new RestTemplate();
4 }
使用的方式很简单,如下:
1 @Autowired
2 private RestTemplate restTemplate;
二、给RestTemplate设置全局Header
在config文件夹下创建HeaderRequestInterceptor.java
1 import org.springframework.http.HttpRequest;
2 import org.springframework.http.MediaType;
3 import org.springframework.http.client.ClientHttpRequestExecution;
4 import org.springframework.http.client.ClientHttpRequestInterceptor;
5 import org.springframework.http.client.ClientHttpResponse;
6
7 import java.io.IOException;
8
9 /**
10 * @author 远猷
11 * @version 1.0.0
12 * @copyright xxx.com
13 * @description RestTemplate拦截器统一添加请求头
14 * @create 2021-04-29 17:40:34
15 */
16 public class HeaderRequestInterceptor implements ClientHttpRequestInterceptor {
17 @Override
18 public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
19 httpRequest.getHeaders().setContentType(MediaType.APPLICATION_JSON);
20 httpRequest.getHeaders().set("Http-Rpc-Type", "JsonContent");
21 httpRequest.getHeaders().set("Http-Rpc-Timeout", "3000");
22 httpRequest.getHeaders().set("app-name", "xxxx");
23 return clientHttpRequestExecution.execute(httpRequest, bytes);
24 }
25 }
在InitBeanConfig的代码中加入
1 @Bean
2 public RestTemplate getRestTemplate() {
3 RestTemplate restTemplate = new RestTemplate();
4 //给所有的Http请求加上请求头
5 restTemplate.setInterceptors(Collections.singletonList(new HeaderRequestInterceptor()));
6 return restTemplate;
7 }
三、对RestTemplate进行错误处理
在config文件夹下创建RestTemplateErrorHandler.java
1 import org.springframework.http.client.ClientHttpResponse;
2 import org.springframework.stereotype.Component;
3 import org.springframework.web.client.ResponseErrorHandler;
4
5 import java.io.IOException;
6
7 /**
8 * @author 远猷
9 * @version 1.0.0
10 * @copyright xxx.com
11 * @description 请求过程日志打印
12 * @create 2021-04-29 20:48:22
13 */
14 @Component
15 public class RestTemplateErrorHandler implements ResponseErrorHandler {
16
17 @Override
18 public boolean hasError(ClientHttpResponse response) throws IOException {
19 // 返回false表示不管response的status是多少都返回没有错
20 // 这里可以自己定义那些status code你认为是可以抛Error
21 return false;
22 }
23
24 @Override
25 public void handleError(ClientHttpResponse response) throws IOException {
26 // 这里面可以实现你自己遇到了Error进行合理的处理
27 System.out.println("handleError" + response);
28 }
29 }
在InitBeanConfig的代码中加入
1 @Bean
2 public RestTemplate getRestTemplate() {
3 RestTemplate restTemplate = new RestTemplate();
4 //给所有的Http请求加上请求头
5 restTemplate.setInterceptors(Collections.singletonList(new HeaderRequestInterceptor()));
6 //给请求的返回值加上自己的业务处理
7 restTemplate.setErrorHandler(new RestTemplateErrorHandler());
8 return restTemplate;
9 }
四、给RestTemplate的Get设置RequestBody参数
RestTemplate支持通过setRequestFactory设置HTTP请求客户端工具,支持jdk、httpclient、okHttp等,默认使用的是SimpleClientHttpRequestFactory,该工程使用的JDK实现,底层使用OutputStream来传递body数据,不支持GET传递body。
我们可以修改为httpclient,只需要使用HttpComponentsClientHttpRequestFactory,但是默认的httpclient的GET请求也是不支持传递body的。有两个用于定义Http请求的基础抽象类:HttpRequestBase、HttpEntityEnclosingRequestBase,前者扩展的不能传递body,而后者可以。引入httpClient依赖:
1 <dependency>
2 <groupId>org.apache.httpcomponents</groupId
3 <artifactId>httpclient</artifactId>
4 <version>4.5.13</version>
5 </dependency>
在config文件夹下创建HttpComponentsClientRestfulHttpRequestFactory.java
1 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
2 import org.apache.http.client.methods.HttpUriRequest;
3 import org.springframework.http.HttpMethod;
4 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
5 import org.springframework.stereotype.Component;
6
7 import java.net.URI;
8
9 /**
10 * @author 远猷
11 * @version 1.0.0
12 * @copyright xxx.com
13 * @description 让RestTemplate的GET请求支持RequestBody参数
14 * @create 2021-04-30 09:26:15
15 */
16 @Component
17 public class HttpComponentsClientRestfulHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
18 @Override
19 protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
20
21 if (httpMethod == HttpMethod.GET) {
22 return new HttpGetRequestWithEntity(uri);
23 }
24 return super.createHttpUriRequest(httpMethod, uri);
25 }
26
27 /**
28 * 定义HttpGetRequestWithEntity实现HttpEntityEnclosingRequestBase抽象类,以支持GET请求携带body数据
29 */
30 private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
31 public HttpGetRequestWithEntity(final URI uri) {
32 super.setURI(uri);
33 }
34
35 @Override
36 public String getMethod() {
37 return HttpMethod.GET.name();
38
39 }
40 }
41 }
在InitBeanConfig的代码中加入
1 @Bean
2 public RestTemplate getRestTemplate() {
3 RestTemplate restTemplate = new RestTemplate();
4 //给所有的Http请求加上请求头
5 restTemplate.setInterceptors(Collections.singletonList(new HeaderRequestInterceptor()));
6 //给请求的返回值加上自己的业务处理
7 restTemplate.setErrorHandler(new RestTemplateErrorHandler());
8 //给RestTemplate的get请求加上RequestBody
9 restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
10 return restTemplate;
11 }
调用方式
1 String requestBody = "param"
2 restTemplate.exchange(url, HttpMethod.GET, new HttpEntity(requestBody, null), Object.class)
RestTemplate的一些坑和改造点的更多相关文章
- springcloud-03-服务注册
新建一个 provider-user 和consumer-movie, user为服务提供者, movie为服务的消费真, 没有什么难的, 直接上代码 microserver-provider-use ...
- 分布式改造剧集之Redis缓存采坑记
Redis缓存采坑记 前言 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...
- RestTemplate踩坑 之 ContentType 自动添加字符集
写在前边 最近在写 OAuth2 对接的代码,由于授权服务器(竹云BambooCloud IAM)部署在甲方内网,所以想着自己 Mock 一下授权方的返回体,验证一下我的代码.我这才踩到了坑-- 故事 ...
- 海豚调度5月Meetup:6个月重构大数据平台,帮你避开调度升级改造/集群迁移踩过的坑
当今许多企业都有着技术架构的DataOps程度不够.二次开发成本高.迁移成本高.集群部署混乱等情况,团队在技术选型之后发现并不适合自己的需求,但是迁移成本和难度又比较大,甚至前团队还留下了不少坑,企业 ...
- shop++改造之ResponseEntity的坑
后台shop++购物车请求的数据是一个Map结构的数据,业务需要要在类似的购物车中加一个套餐. 那么套餐里面就包含商品信息了,觉得不用他的Map了于是封装了两个类: 套餐信息显示类,商品信息显示类 请 ...
- Spring Cloud ZooKeeper集成Feign的坑1,错误:Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
错误如下: ERROR 31473 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** A ...
- springcloud-alibaba手写负载均衡的坑,采用restTemplate,不能添加@loadbalanced注解,否则采用了robbin
采用springcloud-alibaba整合rabbion使用DiscoveryClient调用restful时遇到的一个问题,报错如下: D:\javaDevlepTool\java1.8\jdk ...
- springMvc改造springboot2.0踩坑
1. 支持jsp applicaiton.proerties添加配置 #指定视图解析路径前缀 spring.mvc.view.prefix=/WEB-INF/jsp/ #指定视图解析后缀 spring ...
- H5嵌入原生开发小结----兼容安卓与ios的填坑之路
一开始听说开发H5,以为就是做适配现代浏览器的移动网页,心想不用管IE了,欧也.到今天,发现当初too young too simple,兼容IE和兼容安卓与IOS,后者让你更抓狂.接下来数一下踩过的 ...
- ReactJS webpack实现JS模块化使用的坑
从一个原生HTML/CSS/JS模式的网页改造到ReactJS模块化的结构,需要以下步骤: (1)引用ReactJS框架 ->(2)使用webpack 工具 -> (3)配置webpack ...
随机推荐
- [转帖]Region Merge Config
TiKV replicates a segment of data in Regions via the Raft state machine. As data writes increase, a ...
- 【转帖】AMD EPYC——CPU命名规则
AMD的三代服务器CPU都属于7000系列大锅,那么您如何知道要购买的产品呢? 只要看一下右边的最后一个数字,数字1代表第一代那不勒斯EPYC,数字2代表罗马型号,数字3代表新米兰产品. 始终从右到左 ...
- [转帖]SPECjvm2008 User's Guide
SPECjvm2008 User's Guide https://spec.org/jvm2008/docs/UserGuide.html#UsePJA Version 1.0Last modifie ...
- zabbix监控进程和监控日志
zabbix监控进程和监控日志 文章目录 zabbix监控进程和监控日志 一.自定义监控进程 1.新建脚本存放目录 2.修改zabbix_agentd.conf文件 3.zabbix server端进 ...
- [读书笔记]SQLSERVER企业级平台管理实践读书笔记--从等待事件判断性能瓶颈
用到的系统试图主要有: select * from sys.dm_os_wait_statsselect * from sys.sysprocessesselect * from sys.dm_exe ...
- vue中sync的使用原来这么简单
sync的使用场景 有些时候子组件需要修改父组件传递过来的prop, 要去改变父组件的状态的时候就需要使用aync 看见这里有些同学可能会问?? 不是说不可以修改父组件传递到子组件的值吗? 为啥要修改 ...
- Fabric-ca server端与client端交互
本文介绍Fabric-ca server端和client端的交互过程. 在server端执行Start()命令时,会调用registerHandlers()函数,其作用就是注册处理客户端请求的程序: ...
- P9805 [POI2022~2023R1] ply
1st思路 贪心 当遇到左括号深度加一,可如果当前深度大于 \(H\) 时深度减二,并且 \(ans\) 加一.相当于进行一次翻转操作. 当遇到右括号深度减一,当深度小于零时深度加二,并且 \(ans ...
- c++全局变量extern
extern extern 是 C++ 中的一个关键字,用于声明一个变量或函数是在其他文件中定义的.它的作用是告诉编译器在链接时在其他文件中寻找该变量或函数的定义. 在 C++ 中,如果一个变量或函数 ...
- Django笔记七之ManyToMany和OneToOne介绍
本文首发于本人微信公众号:Hunter后端 原文链接:Django笔记七之ManyToMany和OneToOne介绍 ManyToMany 是一种多对多的关系,在用途和使用方法上和外键 Foreign ...