一、基本介绍
1,什么是 RestTemplate?
(1)RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种可以便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。
RestTemplate 是 Spring 3 中引入的同步阻塞式 HTTP 客户端。根据 Spring 官方文档介绍,在将来的版本中它可能会被弃用,因为他们已在 Spring 5 中引入了 WebClient 作为非阻塞式 Reactive HTTP 客户端。
(2)RestTemplate 定义了 36 个与 REST 资源交互的方法,其中的大多数都对应于 HTTP 的方法。
注意:
严格来说只有 11 个独立的方法,其中有 10 个有三种重载形式,而第 11 个则重载了 6 次,这样一共形成了 36 个方法。
实际上,由于 Post 操作的非幂等性,它几乎可以代替其他的 CRUD 操作。
(1)首先编辑 pom.xml 文件,导入 springboot 的 web 包。
org.springframework.boot
spring-boot-starter-web
(2)接着创建一个 RestTemplate 的配置类,同时设置连接池大小、超时时间、重试机制等等。
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(15000); // 连接超时
factory.setReadTimeout(5000); // 数据读取超时时间
return factory;
}
}
(1)要发起网络请求时直接将 RestTemplate 对象注入使用即可。这里我们请求一个网络接口,并将结果以字符串的形式打印出来。
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public String test() {
String url = "http://jsonplaceholder.typicode.com/posts/1";
return restTemplate.getForObject(url, String.class);
}
}
getForObject() 用于发送一个 HTTP GET 请求。它和 getForEntity() 用法几乎相同。区别在于 getForObject() 返回值返回的是响应体,省略了很多 response 的信息。
下面代码将响应结果映射为一个 String 字符串,并打印出来。
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public void test() {
String url = "http://jsonplaceholder.typicode.com/posts/1";
String str = restTemplate.getForObject(url, String.class);
System.out.println(str);
return;
}
}
(1)由于 getForObject() 包含了将 HTTP 结果转成 POJO 的功能,所以我们可以将其转换成自定义的实体类对象。
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public void test() {
String url = "http://jsonplaceholder.typicode.com/posts/1";
PostBean postBean = restTemplate.getForObject(url, PostBean.class);
System.out.println(postBean.toString());
return;
}
}
(2)其中定义的实体 Bean 代码如下:
@Getter
@Setter
@ToString
public class PostBean {
private int userId;
private int id;
private String title;
private String body;
}
(1)假设接口返回的是一个 json 数组,内容如下:
(2)我们也可以将其转成对应的 Bean 数组
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public void test() {
String url = "http://jsonplaceholder.typicode.com/posts";
PostBean[] arr = restTemplate.getForObject(url, PostBean[].class);
System.out.println("结果数:" + arr.length);
return;
}
}
下面 3 种方式的结果都是一样的。
(1)使用占位符的形式传递参数:
String url = "http://jsonplaceholder.typicode.com/{1}/{2}";
PostBean postBean = restTemplate.getForObject(url, PostBean.class, "posts", 1);
(2)另一种使用占位符的形式:
String url = "http://jsonplaceholder.typicode.com/{type}/{id}";
String type = "posts";
int id = 1;
PostBean postBean = restTemplate.getForObject(url, PostBean.class, type, id);
(3)我们也可以使用 map装载参数:
String url = "http://jsonplaceholder.typicode.com/{type}/{id}";
Map map = new HashMap<>();
map.put("type", "posts");
map.put("id", 1);
PostBean postBean = restTemplate.getForObject(url, PostBean.class, map);
getForEntity() 同样用于发送一个 HTTP GET 请求。它和上面介绍的 getForObject() 用法几乎相同。区别在于 getForEntity() 返回的是 ResponseEntity:
下面代码请求一个网络接口,并将响应体、响应头、响应码打印出来。其中响应体的类型设置为 String。
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public void test() {
String url &