RestTemplate
项目地址:https://gitee.com/firewolf/open-utils/tree/master/RestTemplate
一、简单介绍
RestTemplate是Spring提供的一个类似于HTTPClient的用于模拟http请求模板工具类,在Spring项目中,如果我们需要发起Http请求,可以很方便的使用这个工具类进行处理
二、GET请求
GET请求有两类:getForObject和getForEntity,其中getForObject返回的是响应体,而getForEntity返回的包括:响应行、响应头、响应体,所以这里只讲解getForObject,而忽略到getForObject
-
public <T> T getForObject(URI url, Class<T> responseType)
: 发起get请求,一般用于没有请求参数的时候。
如果有参数的时候,需要拼接在url中,如:http://localhost:8080/user?name=zhangsan&age=123
。
- url:请求的路径
- responseType:希望返回的数据类型
-
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
:使用Map传递参数
使用示例:
Map<String, Object> args = new HashMap<>();
args.put("name", name);
args.put("age", age);
args.put("hobby", StringUtils.join(hobby, ","));
restTemplate.getForObject(USER_URL_GET + "/2?name={name}&age={age}&hobby={hobby}", ResponseVO.class, args);
-
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
: 和上面的方法类似,不同的是需要把所有的参数跟在后面的可变参数中,没有参数的时候也可以。
使用示例:
restTemplate
.getForObject(USER_URL_GET + "/2?name={name}&age={age}&hobby={hobby}", ResponseVO.class, name, age,
StringUtils.join(hobby, ","));
三、POST请求
和GET请求一样,POST请求也有postForObject已经postForEntity两种,区别也在于前者只返回响应体,后者会返回响应头、响应行、响应体
-
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
:发起POST请求,各个参数含义如下:
- url:url地址
- request:请求实体对象
- responseType:响应类型
- uriVariables:url地址参数,如果url地址上没有参数的,这个参数可以不填,使用和 getForObject(String url, Class responseType, Map<String, ?> uriVariables)相同。
需要注意的是,在传递对象的时候,如果我们使用request来传递参数,那么在接受方需要使用@RequestBody来接受参数;
如:
ApiUser u = new ApiUser();
u.setHobby(hobby);
u.setAge(age);
u.setName(name);
return restTemplate.postForObject(USER_URL_POST + "/1", u, ResponseVO.class);
接受方为:
@PostMapping("/1")
public ResponseVO addUser(@RequestBody User user) {
log.info("user-post 1 args: {}", user);
return ResponseVO.ok();
}
如果使用url+uriVariables来传递参数,那么在接受方不需要使用注解来接受参数,而且,这种方式传递数组需要转成,拼接的字符串;
如:
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("age", age);
map.put("hobby", StringUtils.join(hobby,","));
return restTemplate
.postForObject(USER_URL_POST + "/2?name={name}&age={age}&hobby={hobby}", null, ResponseVO.class, map);
接受方为:
@PostMapping("/2")
public ResponseVO addUser2(User user) {
log.info("user-post 2 args: {}", user);
return ResponseVO.ok();
}
2.public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
:这个方法和上面的类似,区别在于可以不传递参数。
- 模拟表单POST提交
//设置请求数据的格式
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//封装参数
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("name", name);
params.add("age", age);
hobby.forEach(x->params.add("hobby",x)); //添加多值,或者是使用,分割的字符串传递数组参数
//封装请求内容
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
return restTemplate
.postForObject(USER_URL_POST + "/2", requestEntity, ResponseVO.class);
接受方:
@PostMapping("/2")
public ResponseVO addUser2(User user) {
log.info("user-post 2 args: {}", user);
return ResponseVO.ok();
}
四、PUT请求
put请求没有返回参数,有三个方法
public void put(String url, @Nullable Object request, Object... uriVariables)
- url:url地址
- request:请求实体对象
- uriVariables:url地址参数,如果url地址上没有参数的,这个参数可以不填,的使用和 public T getForObject(String url,Class responseType,Object… uriVariables)相同。
和POST请求一样,有两种用法:
a.使用request传递参数,那么后台使用@RequestBody接受参数
ApiUser u = new ApiUser();
u.setHobby(hobby);
u.setAge(age);
u.setName(name);
restTemplate.put(USER_URL_PUT + "/1", u);
return ResponseVO.ok();
接受方:
@PutMapping("/1")
public void updateUser(@RequestBody User user) {
log.info("user-post 1 args: {}", user);
}
b.使用url+uriVariables传递参数,那么后台直接使用对象接受参数
@PostMapping("/2")
public ResponseVO putWithURLArgs(String name, Integer age, @RequestParam ArrayList<String> hobby) {
//这种方式传递数组需要用,拼接成字符串
restTemplate.put(USER_URL_PUT + "/2?name={name}&age={age}&hobby={hobby}", null, name, age, StringUtils.join(hobby,","));
return ResponseVO.ok();
}
接受方:
@PutMapping("/2")
public void updateUser2(User user) {
log.info("user-post 2 args: {}", user);
}
五、DELETE请求
public void delete(String url, Map<String, ?> uriVariables)
-
public void delete(String url, Object... uriVariables)
用法类似,就不再过多讲解了,通过url预留参数,再通过uriVariables来绑定参数
六、exchange方法
使用exchange方法可以方便的发起各种请求,方法比较多,但是大同小异,这里以其中一个方法举例说明用法。exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
- url:url地址
- method:http请求方法,通过HttpMethod枚举类获取
- requestEntity:请求实体,可以包含请求头和请求体的信息
- responseType:响应类型
- uriVariables:url地址参数,如果url地址上没有参数的,这个参数可以不填
如利用exchange方法发起post请求@PostMapping("/1") public ResponseVO postWithPojoArgs(String name, Integer age, @RequestParam ArrayList<String> hobby) { ApiUser u = new ApiUser(); u.setHobby(hobby); u.setAge(age); u.setName(name); HttpEntity<ApiUser> httpEntity = new HttpEntity<>(u); ResponseEntity<ResponseVO> exchange = restTemplate .exchange(USER_URL_EXCHANGE + "/1", HttpMethod.POST, httpEntity, ResponseVO.class); return exchange.getBody(); }
接收方:@PostMapping("/1") public ResponseVO addUser(@RequestBody User user) { log.info("user-post 1 args: {}", user); return ResponseVO.ok(); }
推荐阅读
-
Eureka restTemplate访问超时
-
用RestTemplate调取接口,取得返回数据,携带header,动态拼接url ,动态参数
-
@FeignClient 情况下header的传递方法,RestTemplate情况下Header传递方法
-
spring boot项目配置RestTemplate超时时长
-
java分布式基于RestTemplate的使用方法
-
RestTemplate的使用和原理你都烂熟于胸了吗?【享学Spring MVC】
-
为何一个@LoadBalanced注解就能让RestTemplate拥有负载均衡的能力?【享学Spring Cloud】
-
RestTemplate相关组件:ClientHttpRequestInterceptor【享学Spring MVC】
-
java分布式基于RestTemplate的使用方法
-
HttpClient-RestTemplate-Feign