现如今的项目,由服务端向外发起网络请求的场景,基本上处处可见。
RestTemplate是一个执行HTTP请求的同步阻塞式工具类,它仅仅只是在 HTTP 客户端库(例如 JDK HttpURLConnection,Apache HttpComponents,okHttp 等)基础上,封装了更加简单易用的模板方法 API,方便程序员利用已提供的模板方法发起网络请求和处理,能很大程度上提升我们的开发效率
1、前置配置
在spring环境下使用RestTemplate
如果当前项目是SpringBoot
,添加SpringBoot启动依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
同时,将RestTemplate配置初始化为一个Bean对象
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
注意:在这种初始化方法,是使用了JDK
自带的HttpURLConnection
作为底层HTTP
客户端实现。
在需要使用RestTemplate
的位置,注入并使用即可!
@Autowired
private RestTemplate restTemplate;
2、API实战:
RestTemplate
最大的特色就是对各种网络请求方式做了包装,能极大的简化开发人员的工作量,下面我们以GET、POST、PUT、DELETE
为例,分别介绍各个API的使用方式
2.1 GET请求:
2.1.1 不带参的get
请求
@RestController
public class TestController {
/**
* 不带参的get请求
* @return
*/
@RequestMapping(value = "testGet", method = RequestMethod.GET)
public User testGet(){
User user = new User();
user.setCode("200");
user.setMsg("请求成功,方法:testGet");
return user;
}
}
@Data
public class User {
private String code;
private String msg;
}
@Autowired
private RestTemplate restTemplate;
/**
* 单元测试(不带参的get请求)
*/
@Test
public void testGet(){
//请求地址
String url = "http://localhost:8080/testGet";
//发起请求,直接返回对象
User user = restTemplate.getForObject(url, User.class);
}
2.1.2 带参的get请求(使用占位符号传参)
@RestController
public class TestController {
/**
* 带参的get请求(restful风格)
* @return
*/
@RequestMapping(value = "testGetByRestFul/{id}/{name}", method = RequestMethod.GET)
public User testGetByRestFul(@PathVariable(value = "id") String id, @PathVariable(value = "name") String name){
User user = new User();
user.setCode("200");
user.setMsg("请求成功,方法:testGetByRestFul,请求参数id:" + id + "请求参数name:" + name);
return user;
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 单元测试(带参的get请求)
*/
@Test
public void testGetByRestFul(){
//请求地址
String url = "http://localhost:8080/testGetByRestFul/{1}/{2}";
//发起请求,直接返回对象(restful风格)
User user = restTemplate.getForObject(url, User.class, "001", "张三");
}
2.1.3 带参的get请求(restful风格)
@RestController
public class TestController {
/**
* 带参的get请求(restful风格)
* @return
*/
@RequestMapping(value = "testGetByParam", method = RequestMethod.GET)
public User testGetByParam(@RequestParam("userName") String userName,
@RequestParam("userPwd") String userPwd){
User user = new User();
user.setCode("200");
user.setMsg("请求成功,方法:testGetByParam,请求参数userName:" + userName + ",userPwd:" + userPwd);
return user;
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 单元测试(带参的get请求)
*/
@Test
public void testGetByParam(){
//请求地址
String url = "http://localhost:8080/testGetByParam?userName={userName}&userPwd={userPwd}";
//请求参数
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("userName", "唐三藏");
uriVariables.put("userPwd", "123456");
//发起请求,直接返回对象(带参数请求)
User user = restTemplate.getForObject(url, User.class, uriVariables);
}
2.1.4 getForEntity使用示例
上面的所有的getForObject请求传参方法,getForEntity都可以使用,使用方法上也几乎是一致的,只是在返回结果接收的时候略有差别。
使用ResponseEntity<T> responseEntity来接收响应结果。用responseEntity.getBody()获取响应体。
/**
* 单元测试
*/
@Test
public void testAllGet(){
//请求地址
String url = "http://localhost:8080/testGet";
//发起请求,返回全部信息
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class);
// 获取响应体
System.out.println("HTTP 响应body:" + response.getBody().toString());
// 以下是getForEntity比getForObject多出来的内容
HttpStatus statusCode = response.getStatusCode();
int statusCodeValue = response.getStatusCodeValue();
HttpHeaders headers = response.getHeaders();
System.out.println("HTTP 响应状态:" + statusCode);
System.out.println("HTTP 响应状态码:" + statusCodeValue);
System.out.println("HTTP Headers信息:" + headers);
}
header设置参数
//请求头
HttpHeaders headers = new HttpHeaders();
headers.add("token", "123456789");
//封装请求头
HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange('请求的url', HttpMethod.GET, formEntity, String.class);
2.2 GET请求:
其实POST
请求方法和GET
请求方法上大同小异,RestTemplate
的POST
请求也包含两个主要方法:
-
postForObject()
:返回body
对象 -
postForEntity()
:返回全部的信息
2.2.1 模拟表单请求
模拟表单请求,post
方法测试
@RestController
public class TestController {
/**
* 模拟表单请求,post方法测试
* @return
*/
@RequestMapping(value = "testPostByForm", method = RequestMethod.POST)
public User testPostByForm(@RequestParam("userName") String userName,
@RequestParam("userPwd") String userPwd){
User user = new User();
user.setCode("200");
user.setMsg("请求成功,方法:testPostByForm,请求参数userName:" + userName + ",userPwd:" + userPwd);
return user;
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 模拟表单提交,post请求
*/
@Test
public void testPostByForm(){
//请求地址
String url = "http://localhost:8080/testPostByForm";
// 请求头设置,x-www-form-urlencoded格式的数据
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//提交参数设置
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("userName", "唐三藏");
map.add("userPwd", "123456");
// 组装请求体
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
//发起请求
User user = restTemplate.postForObject(url, request, User.class);
}
2.2.2 模拟表单请求,post
方法测试(接收对象)
@RestController
public class TestController {
/**
* 模拟表单请求,post方法测试
* @param request
* @return
*/
@RequestMapping(value = "testPostByFormAndObj", method = RequestMethod.POST)
public User testPostByForm(UserVO request){
User user = new User();
user.setCode("200");
user.setMsg("请求成功,方法:testPostByFormAndObj,请求参数:" + JSON.toJSONString(request));
return user;
}
}
@Data
public class UserVO {
private String userName;
private String userPwd;
}
@Autowired
private RestTemplate restTemplate;
/**
* 模拟表单提交,post请求
*/
@Test
public void testPostByForm(){
//请求地址
String url = "http://localhost:8080/testPostByFormAndObj";
// 请求头设置,x-www-form-urlencoded格式的数据
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//提交参数设置
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("userName", "唐三藏");
map.add("userPwd", "123456");
// 组装请求体
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
//发起请求
User user = restTemplate.postForObject(url, request, User.class);
}
2.2.3 模拟JSON
请求,post
方法测试
@RestController
public class TestController {
/**
* 模拟JSON请求,post方法测试
* @param request
* @return
*/
@RequestMapping(value = "testPostByJson", method = RequestMethod.POST)
public User testPostByJson(@RequestBody UserVO request){
User user = new User();
user.setCode("200");
user.setMsg("请求成功,方法:testPostByJson,请求参数:" + JSON.toJSONString(request));
return user;
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 模拟JSON提交,post请求
*/
@Test
public void testPostByJson(){
//请求地址
String url = "http://localhost:8080/testPostByJson";
//入参
UserVO vo = new UserVO();
vo.setUserName("唐三藏");
vo.setUserPwd("123456789");
//发送post请求,并打印结果,以String类型接收响应结果JSON字符串
ResponseBean responseBean = restTemplate.postForObject(url, vo, User.class);
}
2.3 PUT请求
put
请求方法,可能很多人都没用过,它指的是修改一个已经存在的资源或者插入资源,该方法会向URL
代表的资源发送一个HTTP PUT
方法请求,示例如下
@RestController
public class TestController {
/**
* 模拟JSON请求,put方法测试
* @param request
* @return
*/
@RequestMapping(value = "testPutByJson", method = RequestMethod.PUT)
public void testPutByJson(@RequestBody UserVO request){
System.out.println("请求成功,方法:testPutByJson,请求参数:" + JSON.toJSONString(request));
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 模拟JSON提交,put请求
*/
@Test
public void testPutByJson(){
//请求地址
String url = "http://localhost:8080/testPutByJson";
//入参
UserVO request = new UserVO();
request.setUserName("唐三藏");
request.setUserPwd("123456789");
//模拟JSON提交,put请求
restTemplate.put(url, request);
}
2.4 DELETE请求
与之对应的还有delete
方法协议,表示删除一个已经存在的资源,该方法会向URL
代表的资源发送一个HTTP DELETE
方法请求。
@RestController
public class TestController {
/**
* 模拟JSON请求,delete方法测试
* @return
*/
@RequestMapping(value = "testDeleteByJson", method = RequestMethod.DELETE)
public void testDeleteByJson(){
System.out.println("请求成功,方法:testDeleteByJson");
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 模拟JSON提交,delete请求
*/
@Test
public void testDeleteByJson(){
//请求地址
String url = "http://localhost:8080/testDeleteByJson";
//模拟JSON提交,delete请求
restTemplate.delete(url);
}
2.5 Exchange方法
如果以上方法还不满足你的要求。在RestTemplate
工具类里面,还有一个exchange
通用协议请求方法,它可以发送GET、POST、DELETE、PUT、OPTIONS、PATCH等等HTTP
方法请求。