前言:本篇主要介绍了RestTemplate中的GET,POST,PUT,DELETE、文件上传和文件下载6大常用的功能,每一个方法和每一行代码都进行了详细的讲解,代码都是亲自测试过的,整篇博客写完以后自己也是受益匪浅,于是在这做个技术分享!
目录
RestTemplate是Spring框架用来访问RESTFUL服务的客户端模板类,主要功能有:
1、发起HTTP请求,包括GET,POST,PUT,DELETE等方法。
2、自动将响应结果映射为对象,不用手动解析JSON或XML。
3、设置请求头、消息转码、Cookie等功能。
4、对不同的输入/输出类型提供对应的方法,如字符串、对象、多部分等。
5、支持远程调用,不受同源策略限制。
2.1、先导入pom.xml依赖
org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
2.2、创建RestTemplateConfig配置类
@Configurationpublic class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); }}
2.3、User实体类
package com.example.resttemplate.domain;public class User { public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public int getId() { return id; } public void setId(int id) { this.id = id; } private int id; private String username; private String password; private int sex; private String address; private String phone; private String remark;}
3.1、getForEntity()方法
方法简介:
执行HTTP GET请求,并将返回结果自动封装为指定的Java对象。
方法签名:
ResponseEntity getForEntity(String url, Class responseType, Object... uriVariables)
参数含义:
url:请求的URL。
responseType:响应结果的类型。指定要封装成哪个Java对象,它可以是POJO或者任何Java类型。
uriVariables:URL中的变量,如果URL中有{id}这样的变量,这里就传入具体的值。
3.2、postForObject() 方法
方法简介:
执行HTTP POST请求,并自动将响应结果封装为指定的Java对象。
方法签名:
public T postForObject(String url, Object request, Class responseType, Object... uriVariables)
参数含义:
url:请求的URL。
request:POST请求的实体,可以是任何Java对象。
responseType:响应结果的类型,指定要封装成哪个Java对象。
uriVariables:URL中的变量替换值。
3.3、exchange()方法
方法简介:
执行HTTP请求,并返回ResponseEntity对象。
方法签名:
public ResponseEntity exchange(URI url, HttpMethod method, HttpEntity> requestEntity, Class responseType, Object... uriVariables)
参数含义:
url:请求的URL。
method:请求的HTTP方法,如GET、POST等。
requestEntity:请求的实体,包含请求头和请求体。
responseType:响应结果的类型。
uriVariables:URL中的变量替换值。
3.4、execute()方法
方法简介:
执行HTTP请求,允许高度定制HTTP请求。
参数含义:
url:请求的URL,可以是String或URL对象。
method:HTTP方法,如GET、POST、PUT等。
requestCallback:处理Request的Callback对象,用于定义Request,如设置请求头、查询字符串参数等等。
responseExtractor:处理Response的Callback对象,用于提取Response内容。
3.5、HttpEntity对象
对象简介:
Spring框架定义的数据结构,它表示一个完整的HTTP请求或响应。
它主要有两个作用:
表示HTTP请求:当表示HTTP请求时,HttpEntity有两个主要组成部分:请求头和请求体。
表示HTTP响应当表示HTTP响应时,有三个部分:状态码、响应头和响应体。
通过HttpEntity我们可以方便的构建和处理HTTP请求和响应。
主要参数:
headers:HttpHeaders类型,包括所有头信息。
body:请求或响应体,可以是任何对象。
statusCode:HttpStatus类型,只有在表示响应时才有效。
3.6、RequestCallback对象
RequestCallback是Spring RestTemplate中用来定制HTTP请求的一个接口,可以设置请求头、请求体、查询字符串参数。Callback接口只有一个方法:
void doWithRequest(ClientHttpRequest request) throws IOException
在该方法中可以调用ClientHttpRequest对象的方法来定制Request。
如设置请求头:
new RequestCallback() { public void doWithRequest(ClientHttpRequest request) { request.getHeaders().set("myHeader", "myValue"); }}
设置请求体:
new RequestCallback() { public void doWithRequest(ClientHttpRequest request) { request.getBody() .write(("some data".getBytes()); }}
设置查询参数:
new RequestCallback() { public void doWithRequest(ClientHttpRequest request) { MultiValueMap map= new LinkedMultiValueMap<>(); map.add("param1", "value1"); request.setURI(request.getURI(), map); }}
请求层是这样写的
@RestController@RequestMapping("/user")public class UserController { @GetMapping("/getUserByUsername") public User getUserById(@RequestParam("username") String username, @RequestParam("address") String address){ ....//业务代码 return user; }}
这样写也可以:
@RestController@RequestMapping("/user")public class UserController { @GetMapping("/getUserByUsername") public User getUserById(User user){ ....//业务代码 return user; }}
4.1、参数拼接
直接把参数拼接在url上面:
@Resource private RestTemplate restTemplate; public void sendGet(){ String url = "http://localhost:8080/user/getUserByUsername?username=张三&&address=上海"; ResponseEntity result = restTemplate.getForEntity(url, String.class); System.out.println(result.getStatusCode()); System.out.println(result.getBody()); System.out.println(result.getHeaders()); }
执行结果如下:
4.2、占位符传参
直接在方法中指定参数:
@Resource private RestTemplate restTemplate; public void sendGet(){ String url = "http://localhost:8080/user/getUserByUsername?username={name}&address={address}"; ResponseEntity result = restTemplate.getForEntity(url, String.class,"李四","广东"); System.out.println(result.getStatusCode()); System.out.println(result.getBody()); System.out.println(result.getHeaders()); }
执行结果如下:
通过Map集合传递参数,此种方式必须使用占位符,并且map中的key值,要与请求路径中的占位符一致 :
@Resource private RestTemplate restTemplate; public void sendGet(){ String url = "http://localhost:8080/user/getUserByUsername?username={username}&address={address}"; Map map = new HashMap<>(); map.put("username", "李四"); map.put("address", "广东"); ResponseEntity result = restTemplate.getForEntity(url,String.class,map); System.out.println(result.getStatusCode()); System.out.println(result.getBody()); System.out.println(result.getHeaders()); }
执行结果如下:
4.3、请求头携带Token
定义头信息:
HttpHeaders headers = new HttpHeaders();headers.add("token", UUID.randomUUID().toString());
创建一个HttpEntity对象,用于封装HTTP请求的头信息:
HttpEntity
使用exchange方法发送Get请求:
ResponseEntity result = restTemplate.exchange(url, HttpMethod.GET,entity, String.class);
完整代码:
@Resource private RestTemplate restTemplate; public void sendGet(){ HttpHeaders headers = new HttpHeaders(); headers.add("token", UUID.randomUUID().toString()); String url = "http://localhost:8080/user/getUserByUsername?username=李四&&address=广东"; HttpEntity
执行结果如图:
4.4、请求头携带Cookie
创建一个Cookie:
Cookie cookie = new Cookie("cookie", UUID.randomUUID().toString());
放入请求头当中 :
HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.COOKIE, cookie.toString());
完整代码:
@Resource private RestTemplate restTemplate; public void sendGet(){ Cookie cookie = new Cookie("cookie", UUID.randomUUID().toString()); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.COOKIE, cookie.toString()); String url = "http://localhost:8080/user/getUserByUsername?username=李四&&address=广东"; HttpEntity
执行结果如图:
请求层用到了@RequestBody注解接收参数,具体是这么写的:
@RestController@RequestMapping("/user")public class UserController { @PostMapping("/insert") public String insertUser(@RequestBody User user){ ...//逻辑代码 return message; } }
下面进行发送Post请求测试。
5.1、带@RequestBody
如果请求层是带有@RequestBody注解的,可以通过Json格式进行传参:
@Resource private RestTemplate restTemplate; public void sendPost(){ User user = new User(); user.setId(2); user.setUsername("赵七"); user.setSex(1); user.setPassword("123456"); user.setAddress("江苏"); user.setPhone("123123123"); user.setRemark("无"); String url = "http://localhost:8080/user/insert"; String result = restTemplate.postForObject(url, user, String.class); System.out.println(result); }
运行结果如下:
我们也可以通过Map集合进行传参,效果是一样的:
@Resource private RestTemplate restTemplate; public void sendPost(){ Map map = new HashMap<>(); map.put("id", 5); map.put("username","赵七"); map.put("sex",1); map.put("password","123456"); map.put("address","江苏"); map.put("phone","123123123"); map.put("remark","无"); String url = "http://localhost:8080/user/insert"; String result = restTemplate.postForObject(url, map, String.class); System.out.println(result); }
执行结果如下:
5.2、不带@RequestBody
如果请求层不带这个注解,用上面的两种方法来传递参数是获取不到!
MultiValueMap常用于封装HTTP请求头或查询参数,它可以同一个key下面放多个value,我们也可以通过MultiValueMap集合来进行传递参数:
@Resource private RestTemplate restTemplate; public void sendPost(){ MultiValueMap map = new LinkedMultiValueMap<>(); map.add("id", 5); map.add("username","赵七"); map.add("sex",1); map.add("password","123456"); map.add("address","江苏"); map.add("phone","123123123"); map.add("remark","无"); String url = "http://localhost:8080/user/insert"; String result = restTemplate.postForObject(url, map, String.class); System.out.println(result); }
运行结果如下:
5.3、请求头携带Token
定义头信息:
HttpHeaders headers = new HttpHeaders();headers.add("token", UUID.randomUUID().toString());
使用HttpEntity把请求对象user和header进行组装:
HttpEntity userHttpEntity = new HttpEntity<>(user, headers);
完整代码如下:
@Resource private RestTemplate restTemplate; public void sendPost(){ HttpHeaders headers = new HttpHeaders(); headers.add("token", UUID.randomUUID().toString()); User user = new User(); user.setId(2); user.setUsername("赵七"); user.setSex(1); user.setPassword("123456"); user.setAddress("江苏"); user.setPhone("123123123"); user.setRemark("无"); String url = "http://localhost:8080/user/insert"; // 使用 HttpEntity 把请求对象user 和 header 进行组装 HttpEntity userHttpEntity = new HttpEntity<>(user, headers); String result = restTemplate.postForObject(url, userHttpEntity, String.class); System.out.println(result); }
运行结果如下:
请求层是这么写的:
@RestController@RequestMapping("/user")public class UserController { @PutMapping public String update(@RequestBody User user){ ...//业务代码 return message; }}
6.1、无返回值
直接调用put方式是不带返回值的:
@Resource private RestTemplate restTemplate; public void update(){ String url = "http://localhost:8080/user"; User user = new User(); user.setId(2); user.setUsername("赵七"); user.setSex(1); user.setPassword("123456"); restTemplate.put(url, user); }
执行结果如下:
6.2、带返回值
我们使用exchange方法就可以了,具体代码如下:
@Resource private RestTemplate restTemplate; public void update(){ String url = "http://localhost:8080/user"; User user = new User(); user.setId(2); user.setUsername("赵七"); user.setSex(1); user.setPassword("123456"); HttpEntity body = new HttpEntity<>(user); ResponseEntity result = restTemplate.exchange(url, HttpMethod.PUT,body,String.class); System.out.println(result); }
执行结果如图:
6.3、请求头携带Token
定义头信息:
HttpHeaders headers = new HttpHeaders();headers.add("token", UUID.randomUUID().toString());
使用HttpEntity把请求对象user和header进行组装,然后调用exchange方法即可:
HttpEntity body = new HttpEntity<>(user,headers);ResponseEntity result = restTemplate.exchange(url, HttpMethod.PUT,body,String.class);
请求层是这样写的:
@RestController@RequestMapping("/user")public class UserController { @DeleteMapping("{id}") public String delete(@PathVariable String id){ ...//业务代码 return message; }}
7.1、无返回值
直接调用delete方式是不带返回值的:
@Resource private RestTemplate restTemplate; public void update(){ String url = "http://localhost:8080/user/{id}"; restTemplate.delete(url,1); }
执行结果如图:
7.2、有返回值
使用exchange方法执行即可,具体代码如下:
@Resource private RestTemplate restTemplate; public void update(){ String url = "http://localhost:8080/user/1"; ResponseEntity result = restTemplate.exchange(url, HttpMethod.DELETE,null,String.class); System.out.println(result); }
执行结果如下:
7.3、请求头携带Token
定义头信息
HttpHeaders headers = new HttpHeaders();headers.add("token", UUID.randomUUID().toString());
使用HttpEntity把请求对象user和header进行组装,然后调用exchange方法即可:
HttpEntity body = new HttpEntity<>(headers);ResponseEntity result = restTemplate.exchange(url, HttpMethod.DELETE,body,String.class);
请求层代码:
@RestController@RequestMapping("/user")public class UserController { @PostMapping("/upload") public String upload(MultipartFile file){ return file.getOriginalFilename(); }}
设置请求头:
HttpHeaders headers = new HttpHeaders();headers.add("token", UUID.randomUUID().toString());
创建一个FileSystemResource,将文件封装为resource:
File file = new File("F:/test.jar");FileSystemResource resource = new FileSystemResource(file);
创建一个MultiValueMap,将文件添加进去,键名是"file":
MultiValueMap multiValueMap = new LinkedMultiValueMap<>();multiValueMap.add("file", resource);
使用MultiValueMap和headers创建HttpEntity,表示这是个POST请求,且请求体是文件,发送POST请求到url,请求体是前面创建的HttpEntity:
HttpEntity< MultiValueMap> request = new HttpEntity<>(multiValueMap, headers);ResponseEntity exchange = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
完整代码:
@Resource private RestTemplate restTemplate; public void sendFile(){ String url = "http://localhost:8080/user/upload"; HttpHeaders headers = new HttpHeaders(); headers.add("token", UUID.randomUUID().toString()); File file = new File("F:/test.jar"); FileSystemResource resource = new FileSystemResource(file); MultiValueMap multiValueMap = new LinkedMultiValueMap<>(); multiValueMap.add("file", resource); HttpEntity< MultiValueMap> request = new HttpEntity<>(multiValueMap, headers); ResponseEntity exchange = restTemplate.exchange(url, HttpMethod.POST, request, String.class); System.out.println(exchange); }
执行结果如图:
请求层具体是这么写的:
@RestController@RequestMapping("/user")public class UserController { @GetMapping("/download") public void download(HttpServletResponse response) throws IOException { File file = new File("D:\\test.jar"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=test.jar"); InputStream in = new FileInputStream(file); IOUtils.copy(in, response.getOutputStream()); }}
定义请求头,申明可以接收所有类型的响应内容:
RequestCallback requestCallback = request -> request.getHeaders() .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
使用流的方式读取响应内容,而不是将响应内容全部加载到内存中 :
restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> { Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath)); return null;});
完整代码:
@Resource private RestTemplate restTemplate; public void download() throws MalformedURLException { String url = "http://localhost:8080/user/download"; String targetPath = "test.jar"; RequestCallback requestCallback = request -> request.getHeaders() .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL)); restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> { Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath)); return null; }); }
执行结果如下:
以上就是对于日常使用RestTemplate常用功能的一些汇总,如有异议和遗漏欢迎评论区补充。
来源地址:https://blog.csdn.net/HJW_233/article/details/131582451