作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
本文介绍Spring web中特别牛逼的一个类RestTemplate。
1、RestTemplate概述
发送http请求,估计很多人用过httpclient和okhttp,确实挺好用的,而Spring web中的RestTemplate和这俩的功能类似,也是用来发送http请求的,不过用法上面比前面的2位要容易很多。
spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。
在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。
考虑到RestTemplate类是为调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连就不足为奇了,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate类具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法。
下面给大家上案例,案例是重点,通过案例,把我知道的用法都给盘出来。
2、案例代码
2.1、git地址
https://gitee.com/javacode2018/springmvc-series
2.2、关键代码位置
文中的所有controller代码,在RestTemplateTestController
类中。
所有@Test用例的代码,在RestTemplateTest
。
2.3、如何运行测试用例?
- 拉取项目
- 将chat16-RestTemplate模块发布到tomcat9中
- 运行RestTemplateTest中对应的用例即可
下面咱们来看RestTemplate常见的用法汇总。
3、发送Get请求
3.1、普通请求
接口代码
@GetMapping("/test/get")
@ResponseBody
public BookDto get() {
return new BookDto(1, "SpringMVC系列");
}
使用RestTemplate调用上面这个接口,通常有2种写法,如下
@Test
public void test1() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/chat16/test/get";
//getForObject方法,获取响应体,将其转换为第二个参数指定的类型
BookDto bookDto = restTemplate.getForObject(url, BookDto.class);
System.out.println(bookDto);
}
@Test
public void test2() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/chat16/test/get";
//getForEntity方法,返回值为ResponseEntity类型
// ResponseEntity中包含了响应结果中的所有信息,比如头、状态、body
ResponseEntity<BookDto> responseEntity = restTemplate.getForEntity(url, BookDto.class);
//状态码
System.out.println(responseEntity.getStatusCode());
//获取头
System.out.println("头:" + responseEntity.getHeaders());
//获取body
BookDto bookDto = responseEntity.getBody();
System.out.println(bookDto);
}
test1输出
BookDto{id=1, name='SpringMVC系列'}
test2输出
200 OK
头:[Content-Type:"application/json;charset=UTF-8", Transfer-Encoding:"chunked", Date:"Sat, 02 Oct 2021 07:05:15 GMT", Keep-Alive:"timeout=20", Connection:"keep-alive"]
BookDto{id=1, name='SpringMVC系列'}
3.2、url中含有动态参数
接口代码
@GetMapping("/test/get/{id}/{name}")
@ResponseBody
public BookDto get(@PathVariable("id") Integer id, @PathVariable("name") String name) {
return new BookDto(id, name);
}
使用RestTemplate调用上面这个接口,通常有2种写法,如下
@Test
public void test3() {
RestTemplate restTemplate = new RestTemplate();
//url中有动态参数
String url = "http://localhost:8080/chat16/test/get/{id}/{name}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("id", "1");
uriVariables.put("name", "SpringMVC系列");
//使用getForObject或者getForEntity方法
BookDto bookDto = restTemplate.getForObject(url, BookDto.class, uriVariables);
System.out.println(bookDto);
}
@Test
public void test4() {
RestTemplate restTemplate = new RestTemplate();
//url中有动态参数
String url = "http://localhost:8080/chat16/test/get/{id}/{name}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("id", "1")