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 ...
随机推荐
- [转帖]clickhouse 超底层原理& 高可用集群 实操(史上最全)
https://www.cnblogs.com/crazymakercircle/p/16718469.html 文章很长,而且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵 ...
- [转帖]调优"四剑客"的实战演练,福尔摩斯•K带你轻松优化性能
前言 天下武功,唯快不破.在侦探的世界中,破案效率永远是衡量一名侦探能力的不二法门.作为推理界冉冉升起的新星,大侦探福尔摩斯·K凭借着冷静的头脑.严谨的思维,为我们展现了一场场华丽而热血的推理盛宴. ...
- [转帖]一次SSL握手异常,我发现JDK还有发行版区别
https://www.cnblogs.com/codelogs/p/16633704.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 最近,我们一个 ...
- [转帖]如何提高Linux下块设备IO的整体性能?
http://www.yunweipai.com/6989.html 运维派隶属马哥教育旗下专业运维社区,是国内成立最早的IT运维技术社区,欢迎关注公众号:yunweipai领取学习更多免费Linux ...
- [转帖]OutOfMemory自动重启程序
OutOfMemory以后程序已经假死,无法再提供服务,最好的做法是dump内存,发送警告,然后重启服务 我的方案:利用at命令延迟启动 但有一个问题,at最多支持分钟操作,也就是说要1分钟以后才能启 ...
- Linux 内核参数
/proc/sys/net/ipv4: ip_local_port_range:定义了TCP或UDP对目标发起连接所选择的本地端口范围(除ip_local_reserved_ports之外),其定义受 ...
- Docker与虚拟化技术浅析第一弹之docker与Kubernetes
1 前言 Docker是一个开源的引擎,可以轻松地为任何应用创建一个轻量级的. 可移植的.自给自足的容器.开发者在笔记本电脑上编译测试通过的容器可以批量地在生产环境中部署,包括VMs (虚拟机).ba ...
- TypeScript枚举类型
枚举 简单理解就是将所有的情况列举出来. 枚举不是用来定义类型的哈.就是说枚举不是一种数据类型. enum xxx={ key1=value1, key2=value2, } 通过 xxx.key1的 ...
- 如何写出高质量的代码 data 组件 函数 注释 命名 变量的次数
今天在将以前文件上传的地方全部 改为新的文件上传的api. 在改动的过程中,发现代码有很多不合理的地方 在改的时候,因此也是非常的痛苦的哈. 比如说在data中我有太多的flag标识.俩控制元素的显示 ...
- 【VictoriaMetrics源码阅读】vm中仿照RoaringBitmap的实现:uint64set
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu 公众号:一本正经的瞎扯 正文 VictoriaMetrics中使用uint64类型来表示一个Me ...