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 ...
随机推荐
- SQLServer Core 序列号使用CPU限制的处理
SQLServer Core 序列号使用CPU限制的处理 背景 有客户是SQLSERVER的数据库. 说要进行一下压测. 这边趁着最后进行一下环境的基础搭建工作. 然后在全闪的环境上面搭建了一个Win ...
- [转帖]使用Transformers推理
https://github.com/ymcui/Chinese-LLaMA-Alpaca/wiki/%E4%BD%BF%E7%94%A8Transformers%E6%8E%A8%E7%90%86 ...
- [转帖]【JVM】GC算法与垃圾收集器
引入 java 语言中一个显著的特点就是引入了java回收机制,是c++程序员最头疼的内存管理的问题迎刃而解,它使得java程序员在编写程序的时候不在考虑内存管理.由于有个垃圾回收机制,可以有效的防止 ...
- [转帖]TCP/IP RFC
TCP/IP RFC-阿里云开发者社区 TCP/IP 标准是在一系列称为 RFC 的文档中发布的.RFC 是目前仍在发展的描述 TCP/IP 和 Internet 内部工作的一系列报告.协议的提议以及 ...
- [转贴]汉字编码:GB2312, GBK, GB18030, Big5
汉字编码:GB2312, GBK, GB18030, Big5 https://www.cnblogs.com/malecrab/p/5300497.html 前一篇博文:ANSI是什么编码?中有这样 ...
- Docker内JVM参数的简单学习
Docker内JVM参数的简单学习 背景 公司内部有K8S的项目. 基于K8S内容器的JVM参数的设置与标准虚拟机运行不太一样. 产品内部的启动脚本有一个设置, 在内存大于16G的情况下 默认取内存总 ...
- echarts中x轴文字太长换行的几种方式
我们在使用echarts中,可能会遇见文字太长.导致显示不完全. 我们可以使用换行来处理 第一方式直接使用 \n 文字直接换行显示 使用\n <!DOCTYPE html> <htm ...
- 队列(Queue):先进先出(FIFO)的数据结构
队列是一种基本的数据结构,用于在计算机科学和编程中管理数据的存储和访问.队列遵循先进先出(First In, First Out,FIFO)原则,即最早入队的元素首先出队.这种数据结构模拟了物理世界中 ...
- c++基础之函数
距离上次更新又过了一周,又该更新新的读书笔记了.本次更新的主要是c++中函数部分的内容 c++ 中的函数与c语言中的函数大致用法或者语法是一样的,这里就不就这点详细展开了.需要注意的是c/c++中并没 ...
- 【Jmeter】Request1输出作为Request2输入-后置处理器
[Jmeter]基础介绍-详细 接上文,继续介绍Jmeter,本文关注点为如何解决上文中提到的第一个问题,即: 需要实现Request1的返回作为Request2的RequestBody或Header ...