前言

今天在学习Spring Cloud的过程中无意发现了 RestTemplate 这个Spring 提供的Http Rest风格接口之间调用的模板工具类,感觉比Apache提供的HttpClient更加轻量化,只需要在容器中初始化该对象之后就可以使用,因此决定探索一下。

准备工作

首先创建一个SpringBoot父工程,添加必要的依赖,创建Mysql表,加入一些测试数据:

这里我创建了一个 emp 员工表,添加了两条测试数据,SQL语句如下:

创建表

DROP TABLE IF EXISTS `emp`;

CREATE TABLE `emp` (
`id` bigint(20) NOT NULL COMMENT '主键',
`name` varchar(32) NOT NULL COMMENT '姓名',
`join_time` datetime DEFAULT NULL COMMENT '入职时间',
`sex` tinyint(4) DEFAULT NULL COMMENT '性别 0 未知 1 男 2 女',
`address` varchar(64) DEFAULT NULL COMMENT '地址',
`education_background` varchar(64) DEFAULT NULL COMMENT '教育背景',
`age` tinyint(3) unsigned DEFAULT NULL COMMENT '年龄',
`remark` varchar(128) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /*Data for the table `emp` */ insert into `emp`(`id`,`name`,`join_time`,`sex`,`address`,`education_background`,`age`,`remark`) values (1,'无忧','2020-01-28 21:17:07',1,'陕西省/西安市/雁塔区/某某街道','本科',23,'创始人'),(2,'忘我','2020-01-28 21:18:12',1,'陕西省/西安市/雁塔区/某某街道','本科',22,'合伙人');

逆向生成

接着逆向生成实体类,Mapper和XML文件。这里我参考了博客:坚持到底的博客 博主解释的很详细,我就不重复说明了。

Service和Controller

service和controller 书写起来也比较简单,只是一些基本的CRUD,这里我额外的添加了pageHelper 分页助手插件,为了更好的模拟线上真实环境。

至此,整个项目的目录结构如下:

通过浏览器访问对应的接口地址,获得的数据如下。证明项目已经跑通。准备工作完成:

初步使用RestTemplate

创建项目

新建一个SpringBoot项目,为了方便,我这里只写Controller

利用SpringIOC创建Bean

在启动类中往容器中注入RestTemplate的Bean

@SpringBootApplication
public class BossApplication {
public static void main(String[] args) {
SpringApplication.run(BossApplication.class, args);
} @Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}

使用其Get Api

在新项目中的Controller中注入Bean,然后调用其对应的Api即可快速的通过Http的方式调用接口了

@RestController
@RequestMapping("boss")
public class BossController { @Autowired
private RestTemplate restTemplate; @RequestMapping("employ/{id}")
public ResponseEntity<Emp> employById(@PathVariable Long id){
ResponseEntity<Emp> emp = null;
emp = restTemplate.getForEntity("http://127.0.0.1:9001/emp/" + id, Emp.class);
return emp;
}
}

测试效果如下,可以看到利用9002端口的项目已经调用到9001的项目并成功获取数据:

深入使用

前面我们已经可以初步的使用RestTemplate进行服务之间通过HttpRest请求进行调用了,接下来我们更深入的探索其他的API。Http Rest请求常用的请求方法有4种,分别是 POST、DELETE、PUT、GET。分别对应增删改查4个动作。而在url中加上操作的资源名称。并不出现动词便是我理解的RestFul风格API。下面我对不同的请求方法分别详细介绍其对应的调用方法。

GET

项目中查询的接口一般有两种:根据ID查询详情和根据参数查询列表。根据ID查询详情我已经在前面展示了

这里要说明的就是 getForEntity 和 getForObject 方法,他两的参数是相同的,但返回值类型不同 getForEntity 返回的是 ResponseEntity 对象,在我看来就是将实体类包装,并且携带了响应的状态码,读者可以按需使用。相应的源码如下:

@Nullable
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor(responseType, this.getMessageConverters(), this.logger);
return this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, (Object[])uriVariables);
} // 可以看到,getForEntity 只是对getForObject的结果进行强制类型转换,并没有什么特别的操作
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = this.acceptHeaderRequestCallback(responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = this.responseEntityExtractor(responseType);
return (ResponseEntity)nonNull(this.execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));
}

带请求参数的GET

项目中一般都会有分页条件查询的接口,此时请求参数以key value 形式提交。我们只需要调用对应的重载方法即可

例如有如下接口。根据性别分页查询员工:

@RequestMapping("/list/{sex}/{pageNum}/{pageSize}")
public List<Emp> getByParam(@PathVariable Integer sex,
@PathVariable Integer pageNum,
@PathVariable Integer pageSize){
return empService.getListByPara(pageNum, pageSize, sex);
}

我们通过RestTemplate可以这样查询:

@RequestMapping("employList/{sex}")
public List employById1(@PathVariable Integer sex,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
// 直接返回对象
List emp = null;
Map<String, Object> paraMap = new HashMap<>();
paraMap.put("pageNum", pageNum);
paraMap.put("pageSize", pageSize);
paraMap.put("sex", sex);
// 通过map的形式,spring会将url对应的参数key替换成value
// emp = restTemplate.getForObject("http://127.0.0.1:9001/emp/list/{sex}/{pageNum}/{pageSize}", List.class, paraMap);
// 通过可变参的形式,spring会按顺序替换url中的参数
emp = restTemplate.getForObject("http://127.0.0.1:9001/emp/list/{sex}/{pageNum}/{pageSize}", List.class, pageNum, pageSize, sex);
return emp;
}

以上是完全按照Rest风格的GET url,参数都是在url上以PathVariable 的形式出现的,但如果参数不在url上,就需要稍加修改了

非Rest风格GET请求

我们知道,GET请求的请求参数一般都在url上拼接。url后面以 ? 开始,key=value 的形式拼接多个请求参数。多个键值对之间用 & 符号连接。我琢磨了很久也只发现了字符串拼接这种传参方式,(惭愧,回去该好好读读 http 请求相关的书籍了)如果读者发现了更好的方法请不吝赐教!实现代码如下:

@RequestMapping("employList1/{sex}")
public List employList1(@PathVariable Integer sex,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
HttpServletRequest request) {
// 直接返回对象
List emp = null;
// 请求参数
Map<String, Object> map= new HashMap<>();
map.put("pageNum", pageNum);
map.put("pageSize", pageSize);
map.put("sex", sex);
// 在url中拼接参数,然后由spring从map中将值替换
emp = restTemplate.getForObject("http://127.0.0.1:9001/emp/list/{sex}" + "?pageNum={pageNum}&pageSize={pageSize}", List.class, map);
return emp;
}

POST

项目中,POST请求一般以JSON的形式发送。基本的发送方法很简单。将对象打包好扔到方法的第二个参数就可以发送了

@RequestMapping("new")
public int addEmploy(@RequestBody Emp emp) {
return restTemplate.postForObject("http://127.0.0.1:9001/emp/new", emp, Integer.class);
}

PS:在测试 POST 请求的过程中我发现了两处配置问题

  1. 插入的数据乱码,这个需要在数据库连接url中加参数。设置编码位 utf8
url: jdbc:mysql://192.168.25.128:3306/mysql?characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT

  1. 之前写的 select * 查询没有开启mysql下划线到Java驼峰的自动转换,导致入职日期,教育背景字段没有读取成功

这个在 application.yml 中可以配置:

mybatis:
mapper-locations: classpath:cn/keats/mapper/*Mapper.xml
configuration:
map-underscore-to-camel-case: true

PUT DELETE

put 请求类似于 post,delete 请求类似于 get。这里就不在赘述了

后记

RestTemplate的介绍就到这里了,以上的方法基本涵盖了项目目前所有的接口,使用RestTemplate给我的感受就是如果接口完全按照Rest风格书写,使用其方法很简单,基本上一行代码就调用成功了。如果不是完全按照Rest风格的接口就需要多花费一些时间来二次封装接口了。推荐调用Rest风格API时候使用。

GITHUB项目地址

此博客的所有代码都已经同步上传至我的GITHUB仓库中,想要练手的朋友不妨克隆下来使用

RestTemplate 使用介绍 RestTemplate发送GET、POST请求的示例项目

RestTemplate---Spring提供的轻量Http Rest 风格API调用工具的更多相关文章

  1. 推荐轻量友好的.NET测试断言工具Shouldly

    Shouldly是一个轻量的断言(Assertion)框架,用于补充.NET框架下的测试工具.Shouldly将焦点放在当断言失败时如何简单精准的给出很好的错误信息. Shouldly在GitHub的 ...

  2. Spring Boot & Cloud 轻量替代框架 Solon 1.3.37 发布

    Solon 是一个微型的Java开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Micro service.WebSocket. ...

  3. Spring Boot & Cloud 轻量替代框架 Solon 1.3.33 发布

    Solon 是一个微型的Java开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Micro service.WebSocket. ...

  4. Spring Boot & Cloud 轻量替代框架 Solon 1.4.1 发布

    Solon 是一个微型的Java开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Micro service.WebSocket. ...

  5. Spring Boot & Cloud 轻量替代框架 Solon 1.3.35 发布

    Solon 是一个微型的Java开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Micro service.WebSocket. ...

  6. 基于netty轻量的高性能分布式RPC服务框架forest<上篇>

    工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...

  7. 五款轻量型bug管理工具横向测评

    五款轻量型bug管理工具横向测评 最近正在使用的本地bug管理软件又出问题了,已经记不清这是第几次了,每次出现问题都要耗费大量的时间精力去网上寻找解决方案,劳心劳力.为了避免再次出现这样的情况,我决定 ...

  8. 对标 Spring Boot & Cloud ,轻量框架 Solon 1.5.2 重要发布

    Solon 是一个轻量的Java基础开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Job.Micro service.WebS ...

  9. 对标 Spring Boot & Cloud ,轻量框架 Solon 1.5.8 发布

    Solon 是一个轻量的Java基础开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Job.Micro service.WebS ...

随机推荐

  1. UI 素材相关收集

    图标素材收藏网址  阿里:iconfont.cn 图片压缩:https://tinypng.com/ gif动图压缩:https://tool.gifhome.com

  2. deep Q learning小笔记

    1.loss 是什么 2. Q-Table的更新问题变成一个函数拟合问题,相近的状态得到相近的输出动作.如下式,通过更新参数 θθ 使Q函数逼近最优Q值 深度神经网络可以自动提取复杂特征,因此,面对高 ...

  3. 试着用教程跑cifar10数据

    1.terminal里已经可import torchvision了,为什么Spyder里还是不能import torchvision 重启. 2. trainset = torchvision.dat ...

  4. PSR-1之PHP代码文件必须以不带BOM的UTF-8编码

    BOM——Byte Order Mark,就是字节序标记 在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE“的字符,它的编码是FEFF.而FFFE在UCS中是不存在的字符 ...

  5. com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1680 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.

    这个错误是由于mysql的一个系统参数max_allowed_packet设置的值过小引起的 解决这个错误的方法就是修改这个参数的值, linux系统中我们在etc目录下找到my.cnf这个文件,打开 ...

  6. linux-iptables匹配条件总结(一)

    指定单个ip,示例如下: iptables -A INPUT -s 192.168.2.85 -j ACCEPT ![](https://img2018.cnblogs.com/blog/189009 ...

  7. 20191121-9 Scrum立会报告+燃尽图 05

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/10069 一: 组名:组长组 组长:杨天宇 组员:魏新  罗杨美慧  王歆 ...

  8. OpenVINO 入门

    关于OpenVINO 入门,今天给大家分享一个好东西和好消息! 现如今,说人工智能(AI)正在重塑我们的各行各业绝不虚假,深度学习神经网络的研究可谓如火如荼, 但这一流程却相当复杂,但对于初学者来说也 ...

  9. 【瞎讲】 Cayley-Hamilton 常系数齐次线性递推式第n项的快速计算 (m=1e5,n=1e18)

    [背诵瞎讲] Cayley-Hamilton 常系数齐次线性递推式第n项的快速计算 (m=1e5,n=1e18) 看CSP看到一题"线性递推式",不会做,去问了问zsy怎么做,他并 ...

  10. 洛谷P1029 最大公约数和最小公倍数问题 题解

    题目链接:https://www.luogu.com.cn/problem/P1029 题目描述 输入 \(2\) 个正整数 \(x_0,y_0(2 \le x_0 \lt 100000,2 \le ...