![8aec8f5625ba45c42bf94d31771ef42c.png](https://i-blog.csdnimg.cn/blog_migrate/66765296c84a7bea1fdb6c7f5f0c4d6d.jpeg)
一 RestTemplate 是啥?
它有一个强大的爸爸 Spring。
Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。它的堂兄:Http Client。(有了它,堂兄就用的少了)
既然是 Http 服务,那就少不了各种请求。
Show me your code , no can no bb。
在 RestTemplate 中发送 GET 请求:
二 使用 getForObject()
![20bd83eb552d23f002b0a09bdc24954d.png](https://i-blog.csdnimg.cn/blog_migrate/911348b0fc4668ff504f483c0b4320e7.png)
先来看下 getForObject 的 API 说明:
getForObject(String url, Class<T> responseType, Object... uriVariables) T
参数说明:
- String url : 调用的服务的 url
- Class<T> responsetype : 返回对象的类型
- Object... uriVariables : url 中的可变参数(配合占位符使用)
- T :返回类型,泛型
getForObject(URI url, Class<T> responseType) T
参数说明:
- URI url : URI 类型的地址
- Class<T> responsetype : 返回对象的类型
- T : 返回类型,泛型
getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) T
参数说明:
- String url : 调用的服务的 url
- Class<T> responsetype : 返回对象的类型
- Map<String, ?> uriVariables : url 中的可变参数(配合占位符使用)
- T : 返回类型,泛型
1 传入一个值,返回一个对象的情况:
(列举了常用的,没有面面俱到,可以照猫画虎)
1.1 直接将变量写在 url 中,记得添加注解 @PathVariable
// 参数拼接
@GetMapping("/user/{id}")
public User findUserById(@PathVariable Long id){
return restTemplate.getForObject("http://localhost:8000/user/"+id, User.class);
}
这里的User.class 即代表返回的参数类型。
![9de0ae3138be0a98d3c3edf03f3e0e06.png](https://i-blog.csdnimg.cn/blog_migrate/be5e7f26cd1da0e3840ba83574351d5e.png)
1.2 将变量通过key=word形式传递,
通过 HttpServletRequest 获取参数
// 地址栏 key=value 形式传参
@GetMapping("/req")
public User findAUser(HttpServletRequest request){
String id = request.getParameter("id");
return restTemplate.getForObject("http://localhost:8000/req?id="+id, User.class);
}
结果:
![12e61a9058aa7c75764b2a75acddb141.png](https://i-blog.csdnimg.cn/blog_migrate/6509ff18ebaf98313d2c54c252a5b09b.png)
1.3 通过占位符:
// 参数的不同传法 数字占位符
@GetMapping("/one/{id}")
public User findOneUser(@PathVariable Long id){
return restTemplate.getForObject("http://localhost:8000/user/{0}",User.class, id);
}
{0} 的具体值来自于 id。
其实我试了花括号里面任意的值都可以,因为现在仅传递了一个参数。
1.4 通过占位符,结合 Map:
// 参数的不同传法,Map类型
@GetMapping("/one/{id}")
public User findOneUser(@PathVariable Long id){
Map<String, Long> map = new HashMap<String, Long>();
map.put("id",id);
return restTemplate.getForObject("http://localhost:8000/user/{id}", User.class, map);
}
更适合有多个参数的情况。
花括号里面的名字值和 map 的键名字保持一致即可,就可以传递对应的值。
1.5 通过 URI 进行 访问:
@GetMapping
使用 Spring 的 UriComponents 工具,参数可以整合到路径中。
▌一种方法可以直接拼接,如上图。
▌另外一种可以利用占位符,通过 expand() 方法实现。如下:
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://localhost:8000/req?id={id}").
build().expand(id).encode();
.build.expand(id).encode。
2 传入一个值,返回一个列表的情况:
尝试使用 List<User> 作为返回类型,编译阶段就报错。改为 User[] 数组。
// 返回多个对象(jpa中是list列表)
@GetMapping("/users")
public User[] findAllUser(){
return restTemplate.getForObject("http://localhost:8000/users", User[].class);
}
注意函数的第二个参数 User[].class。
![cc0cda1c1a0b602d9d680d850a433687.png](https://i-blog.csdnimg.cn/blog_migrate/607d4070d9e0931290a8ad1bd7dd8d48.jpeg)
三 使用 getForEntity()
![fe4bf3c162cad14d14eb770c198c5a1e.png](https://i-blog.csdnimg.cn/blog_migrate/f9ec118add7aa2d3cca52146b4b59139.png)
也是有 3 个重载的方法,和 getForObject 一样。(不对,应该说 getForObject 和它一样,getForObject 是对它的封装)
为什么呢?看它的返回值,是 ResponseEntity<T> 。
通过代码来探讨一下:
@GetMapping("/user/{id}")
public ResponseEntity<String> findUserById(@PathVariable Long id){
//return restTemplate.getForObject("http://localhost:8000/user/"+id, User.class);
return restTemplate.getForEntity("http://localhost:8000/user/"+id, String.class);
}
函数中第二个参数 String.class ,必须和 ResponseEntity<T> 中的 T 保持一致。也可以设置成 User.class。T 为 User。
在 Postman 中结果是这样的:
![f7cc15b61a3559b9a32f8d95b1143d20.png](https://i-blog.csdnimg.cn/blog_migrate/81386325a01c5dc69f3859fe27d7abd3.png)
看上去没有什么异同。这是因为工具直接封装,直接拿到了Json 类型的数据。稍作改变:
@GetMapping("/user/{id}")
public String findUserById(@PathVariable Long id){
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8000/user/"+id,
String.class);
String body = responseEntity.getBody();
HttpStatus statusCode = responseEntity.getStatusCode();
int statusCodeValue = responseEntity.getStatusCodeValue();
HttpHeaders headers = responseEntity.getHeaders();
StringBuffer result = new StringBuffer();
StringBuffer sb = new StringBuffer();
sb.append("body: ").append(body).append("n statusCodeValue: ").append(statusCodeValue).
append("n headers: ").append(headers).append("n statusCode: ").append(statusCode);
return sb.toString();
}
可以看到,ResponseEntity 类型的返回值是 Spring 对 HTTP 请求响应的封装,包括了几个重要的元素,如statusCode、headers、响应消息体等。
在 Postman 中查看结果:
![13908431c5fda48a23071c707c819d8c.png](https://i-blog.csdnimg.cn/blog_migrate/b8cf8eb394bfc289d22bf9d1b89bcb1b.png)
其他的使用方法都与 getForObject 大同小异。如果直接只需要返回结果,getForObject 更胜一筹,毕竟越封装,对使用人员越是傻瓜式使用。
读到这里,你对 getForObject 和 getForentity 有了新的认识了吗?
别怕,如果还有些生疏,再亲自敲一遍就可以了。(前提要会搭建一个服务,如果还不会,可以找我)
放一下可以找到我的原文链接,也是该文章的首发地址。
记录 RestTemplate 中的 GET 请求mp.weixin.qq.com![1f7c8ae62064b312bd2341d89e6411e4.png](https://i-blog.csdnimg.cn/blog_migrate/76a79c46b080591ff30d2edd17b3144e.png)
谢谢阅读,祝有收获。