H__D  

RestTemplate介绍

  调用远程服务时就必须使用HTTP客户端,主要有四种:JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。  

  解放了原先HttpClient的复杂提交,java中调用RESTful服务很典型的是使用HttpClient,对于常用的REST操作,这些方法属于低等级的操作。使用HttpClient我们需要自己封装Post请求,再根据响应的状态码判断从响应中获取header和body,有时候还需要自己做json转换。

  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()等方法。

RestTemplate实现

  最新api地址:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

  RestTemplate包含以下几个部分:

  • HttpMessageConverter 对象转换器
  • ClientHttpRequestFactory 默认是JDK的HttpURLConnection
  • ResponseErrorHandler 异常处理
  • ClientHttpRequestInterceptor 请求拦截器

  RestTemplate是spring的一个rest客户端,在spring-web这个包下,spring boot的依赖如下:

1 <dependency>
2     <groupId>org.springframework.boot</groupId>
3     <artifactId>spring-boot-starter-web</artifactId>
4 </dependency>

  点进去可以看到spring-web

1 <dependency>
2     <groupId>org.springframework</groupId>
3     <artifactId>spring-web</artifactId>
4     <version>5.1.9.RELEASE</version>
5 </dependency>

  所以如果在非spring的框架下直接引入spring-web这个包即可。

  RestTemplate有三个实现

 1 package org.springframework.web.client;
 2 
 3 public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
 4 
 5     ...
 6 
 7     public RestTemplate() {
 8         ...
 9     }
10 
11     public RestTemplate(ClientHttpRequestFactory requestFactory) {
12         ...
13     }
14 
15     public RestTemplate(List<HttpMessageConverter<?>> messageConverters) {
16         ...
17     }
18 }

RestTemplate使用

  新建一个SpringBoot Web工程,引入依赖spring-boot-starter-web

1  <dependency>
2         <groupId>org.springframework.boot</groupId>
3         <artifactId>spring-boot-starter-web</artifactId>
4 </dependency>

  1、restTemplate获取字符串

    REST API代码

1 @RequestMapping(value = "/employees", produces = MediaType.TEXT_HTML_VALUE, method = RequestMethod.GET)
2 public String getAllEmployeesHtml(Model model)
3 {
4     model.addAttribute("employees", employeeMapper.getEmps());
5     return "employees";
6 }

    REST客户端代码

1 // 获取字符串
2 @Test
3 public void test01() {
4     String url = "http://localhost:8080/employees";
5             String res1 = restTemplate.getForObject(url, String.class);
6     System.out.println("getForObject======" + res1);
7 }

  2、使用RestTemplate的自定义HTTP标头

    REST API代码

1 @RequestMapping(value = "/employees", produces = MediaType.APPLICATION_JSON_VALUE,  method = RequestMethod.GET)
2 @ResponseBody
3 public List<Employee>  getAllEmployeesJSON()
4 {
5     return employeeMapper.getEmps();
6 }

    REST客户端代码

// 使用RestTemplate的自定义HTTP标头
@Test
public void test02(){
    String url = "http://localhost:8080/employees";
            HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);

    ResponseEntity<String> res2 = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
    System.out.println("exchange======" + res2);
}

  3、获取响应作为对象

    REST API代码

1 @RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
2 @ResponseBody
3 public Employee get(@PathVariable("id") Integer id){
4     return employeeMapper.getEmpById(id);
5 }

    REST客户端代码

 1 // 获取响应作为对象
 2 @Test
 3 public void test03(){
 4     String url = "http://localhost:8080/employee/1";
 5 
 6     Employee res3 = restTemplate.getForObject(url, Employee.class);
 7     System.out.println("getForObject======" + res3);
 8 }
 9 
10 // 获取响应作为对象,并获取响应对象状态
11 @Test
12 public void test033(){
13     String url = "http://localhost:8080/employee/1";
14     ResponseEntity<Employee> res3 = restTemplate.getForEntity(url, Employee.class);
15     System.out.println("getStatusCode======" + res3.getStatusCode());
16     System.out.println("getForEntity======" + res3);
17 }

  4、URL参数

    REST API代码

1 @RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
2 @ResponseBody
3 public Employee get(@PathVariable("id") Integer id){
4     return employeeMapper.getEmpById(id);
5 }

    REST客户端代码

 1 // URL参数
 2 @Test
 3 public void test04(){
 4     String url = "http://localhost:8080/employee/{id}";
 5 
 6     Map<String, String> params = new HashMap<String, String>();
 7     params.put("id", "1");
 8     Employee res4 = restTemplate.getForObject(url, Employee.class, params);
 9     System.out.println("getForObject======" + res4);
10 }

   5、HTTP POST方法

    REST API代码

1 @RequestMapping(value = "/employee", method = RequestMethod.POST)
2 @ResponseBody
3 public String save(@RequestBody Employee employee){
4     System.out.println("post ====" + employee);
5     return "success";
6 }

    REST客户端代码

1 // HTTP POST方法
2 @Test
3 public void test05(){
4     String url = "http://localhost:8080/employee";
5 
6     Employee newEmployee = new Employee(-1, "小黑", "1", "test@email.com");
7     String res5 = restTemplate.postForObject(url, newEmployee, String.class);
8     System.out.println("postForObject======" + res5);
9 }

  6、HTTP PUT方法示例

    REST API代码

1 @RequestMapping(value = "/employee", method = RequestMethod.PUT)
2 @ResponseBody
3 public String update(@RequestBody Employee employee){
4     System.out.println("put ====" + employee);
5     return "success";
6 }

    REST客户端代码

1 // HTTP PUT方法示例
2 @Test
3 public void test06(){
4     String url = "http://localhost:8080/employee";
5     Employee newEmployee = new Employee(-1, "小黑", "1", "test@email.com");
6     restTemplate.put(url, newEmployee);
7 }

  7、HTTP DELETE方法示例

    REST API代码

1 @RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
2 @ResponseBody
3 public String delete(@PathVariable("id") Integer id){
4     System.out.println("delete ====" + id);
5     return "success";
6 }

    REST客户端代码

1 // HTTP DELETE方法示例
2 @Test
3 public void test07(){
4     String url = "http://localhost:8080/employee/1";
5     restTemplate.delete(url);
6 }

 

 

posted on 2020-04-01 00:01  H__D  阅读(9310)  评论(1编辑  收藏  举报