# RestTemplate **Repository Path**: tangcco/rest-template ## Basic Information - **Project Name**: RestTemplate - **Description**: Springboot 集合 Spring RestTemplate 实现 restfull编程风格 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 2 - **Created**: 2021-01-20 - **Last Updated**: 2022-08-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RestTemplate   SpringRestTemplate是Spring 提供的用于访问 Rest 服务的客端, RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端比如Android或者第三方服务商都是使用RestTemplate 请求 restful服务 ## 1.环境搭建   为了演示RestTemplate的使用,我们创建两个SpringBoot项目,一个provider作为server端,一个consumer作为服务调用方法 ## 2.API方法介绍 | API | 说明 | | ----------------- | ------------------------------------------------------------ | | getForEntity() | 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象 | | getForObject() | 发送一个HTTP GET请求,返回的请求体将映射为一个对象 | | postForEntity() | POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的 | | postForObject() | POST 数据到一个URL,返回根据响应体匹配形成的对象 | | headForHeaders() | 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头 | | optionsForAllow() | 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息 | | postForLocation() | POST 数据到一个URL,返回新创建资源的URL | | put() | PUT 资源到特定的URL | | delete() | 在特定的URL上对资源执行HTTP DELETE操作 | | exchange() | 在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的 | | execute() | 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象 | ## 3.具体使用   我们通过常用的http协议的四种请求方式来看下效果 ### 3.1 无参请求   我们先来看下服务端请求方法不需要接收参数, #### getForEntity   通过getForEntity来实现 服务端 ```java /** * 无参,返回字符串 * @return */ @GetMapping("/server1") public String server1String(){ System.out.println("服务端被访问了..."); return "success"; } 123456789 ``` 调用 ```java /** * RestTemplate 访问 provider的第一个服务 server1 */ @Test public void contextLoads() { String url = "http://localhost:8080/server1"; RestTemplate restTemplate = new RestTemplate(); ResponseEntity entity = restTemplate.getForEntity(url, String.class); // 获取响应的状态 HttpStatus statusCode = entity.getStatusCode(); // 获取响应的header信息 HttpHeaders headers = entity.getHeaders(); // 获取响应的body信息 String msg = entity.getBody(); System.out.println(statusCode); System.out.println(headers); System.out.println(msg); } 123456789101112131415161718 ``` 输出结果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190529115246749.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9kcGItYm9ib2thb3lhLXNtLmJsb2cuY3Nkbi5uZXQ=,size_16,color_FFFFFF,t_70) 说明: > 1.getForEntity()方法执行返回的类型是ResponseEntity,ResponseEntity是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等,在输出结果中我们能够看到 > 2.getForEntity()的参数中第一个是请求地址,第二个是T对应的类型 #### getForObject   getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject ```java /** * getForObject 访问 */ @Test public void contextLoadsObject() { String url = "http://localhost:8080/server1"; RestTemplate restTemplate = new RestTemplate(); // 直接返回的就是我们需要的结果,但是获取不到对应的响应状态等信息 String msg = restTemplate.getForObject(url,String.class); System.out.println(msg); } 1234567891011 ``` ### 3.2 有参请求 服务端方法需要接收调用者传递的参数 ```java /** * 有参,基本数据类型 返回字符串 * @return */ @RequestMapping("/server2") public String server2String(Integer id,String userName){ System.out.println("服务端被访问了..."+id+" "+userName); return "success--参数得到了"; } /** * 有参,基本数据类型 返回字符串 * @return */ @RequestMapping("/server3") public String server3String(User user){ System.out.println("服务端被访问了..."+user); return "success--参数得到了"; } 12345678910111213141516171819 ``` #### getForEntity 调用者可以通过两种方式调用 第一种方式通过数字占位符,最后是一个可变长度的参数,来一一替换前面的占位符 ```java /** * 请求服务并且传递参数 * 基本数据类型 */ @Test public void testServer2(){ // 参数在链接地址后 String url = "http://localhost:8080/server2?id={1}&userName={2}"; RestTemplate restTemplate = new RestTemplate(); ResponseEntity entity = restTemplate.getForEntity(url, String.class,5,"bobo"); System.out.println(entity.getBody()); } 123456789101112 ``` 第二种就是使用name={name}这种形式,最后一个参数是一个map,map的key即为前边占位符的名字,map的value为参数值 ```java /** * 请求服务并且传递参数 * 基本数据类型 */ @Test public void testServer3(){ String url = "http://localhost:8080/server2?id={id}&userName={userName}"; Map map = new HashMap<>(); map.put("id",6); map.put("userName","波波烤鸭"); RestTemplate restTemplate = new RestTemplate(); ResponseEntity entity = restTemplate.getForEntity(url, String.class,map); System.out.println(entity.getBody()); } 1234567891011121314 ``` #### postForEntity   如果是post方式提交请求传递参数我们可以这样使用,如下 服务端:注意要加@RequestBody注解 ```java /** * 有参,基本数据类型 返回字符串 * @return */ @RequestMapping("/server3") public String server3String(@RequestBody User user){ System.out.println("服务端被访问了..."+user); return "success--参数得到了"; } 123456789 ``` 客户端 ```java /** * postForEntity(url,user,String.class) * url:请求地址 * user:请求提交的数据 * String.class 接收返回数据的类型 */ @Test public void contextLoadsObject1() { String url = "http://localhost:8080/server3"; RestTemplate restTemplate = new RestTemplate(); User user = new User(1,"bobo","中国"); // 直接返回的就是我们需要的结果,但是获取不到对应的响应状态等信息 String msg = restTemplate.postForEntity(url,user,String.class).getBody(); System.out.println(msg); } 123456789101112131415 ``` ### 3.3 返回自己类型   服务端返回的我们自定义类型的数据 ```java /** * 返回自定义对象 * @return */ @RequestMapping("/server4") public User server4Object(){ System.out.println("服务端被访问了..."); return new User(2,"李四","深圳"); } 123456789 ``` 客户端: ```java /** * 返回类型为自定义类型 */ @Test public void testServer5(){ String url = "http://localhost:8080/server4"; RestTemplate restTemplate = new RestTemplate(); ResponseEntity entity = restTemplate.getForEntity(url, User.class); System.out.println(entity.getBody()); } 12345678910 ``` 使用getForEntity和getForObject及postForEntity和postForObject都差不多,注意接收的类型即可。 ### 3.4 返回的list带泛型的场景   此处我们需要使用到exchange方法,特定如下 1. 允许调用者指定HTTP请求的方法(GET,POST,PUT等) 2. 可以在请求中增加body以及头信息,其内容通过参‘HttpEntityrequestEntity’描述 3. exchange支持‘含参数的类型’(即泛型类)作为返回类型,该特性通过‘ParameterizedTypeReferenceresponseType’描述 ```java /** * 返回 集合带泛型 * @return */ @RequestMapping("/server5") public List server5List(){ System.out.println("服务端被访问了..."); return Arrays.asList(new User(2,"李四1","深圳") ,new User(3,"李四2","深圳") ,new User(4,"李四3","深圳")); } 1234567891011 ``` 客户端调用 ```java /** * 返回类型为List带泛型 */ @Test public void testServer6(){ String url = "http://localhost:8080/server5"; RestTemplate restTemplate = new RestTemplate(); // 注意后面有一对{} ParameterizedTypeReference本身是抽象类 ParameterizedTypeReference> pr = new ParameterizedTypeReference>() {}; ResponseEntity> exchange = restTemplate.exchange(url, HttpMethod.GET, null, pr); System.out.println(exchange.getBody()); } ```