SpringBoot整合RestTemplate用法的實(shí)現(xiàn)
前言:本篇主要介紹了RestTemplate中的GET,POST,PUT,DELETE、文件上傳和文件下載6大常用的功能,每一個(gè)方法和每一行代碼都進(jìn)行了詳細(xì)的講解,代碼都是親自測(cè)試過(guò)的,整篇博客寫(xiě)完以后自己也是受益匪淺,于是在這做個(gè)技術(shù)分享!
一、RestTemplate簡(jiǎn)介
RestTemplate是Spring框架用來(lái)訪問(wèn)RESTFUL服務(wù)的客戶端模板類(lèi),主要功能有:
1、發(fā)起HTTP請(qǐng)求,包括GET,POST,PUT,DELETE等方法。
2、自動(dòng)將響應(yīng)結(jié)果映射為對(duì)象,不用手動(dòng)解析JSON或XML。
3、設(shè)置請(qǐng)求頭、消息轉(zhuǎn)碼、Cookie等功能。
4、對(duì)不同的輸入/輸出類(lèi)型提供對(duì)應(yīng)的方法,如字符串、對(duì)象、多部分等。
5、支持遠(yuǎn)程調(diào)用,不受同源策略限制。
二、基礎(chǔ)配置
2.1、先導(dǎo)入pom.xml依賴(lài)
<dependencies>
<!-- RestTemplate需要的依賴(lài) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok依賴(lài) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 單元測(cè)試依賴(lài) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>2.2、創(chuàng)建RestTemplateConfig配置類(lèi)
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}2.3、User實(shí)體類(lèi)
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;
}三、對(duì)象和方法講解
3.1、getForEntity()方法
方法簡(jiǎn)介:
執(zhí)行HTTP GET請(qǐng)求,并將返回結(jié)果自動(dòng)封裝為指定的Java對(duì)象。
方法簽名:
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
參數(shù)含義:
url:請(qǐng)求的URL。
responseType:響應(yīng)結(jié)果的類(lèi)型。指定要封裝成哪個(gè)Java對(duì)象,它可以是POJO或者任何Java類(lèi)型。
uriVariables:URL中的變量,如果URL中有{id}這樣的變量,這里就傳入具體的值。
3.2、postForObject() 方法
方法簡(jiǎn)介:
執(zhí)行HTTP POST請(qǐng)求,并自動(dòng)將響應(yīng)結(jié)果封裝為指定的Java對(duì)象。
方法簽名:
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
參數(shù)含義:
url:請(qǐng)求的URL。
request:POST請(qǐng)求的實(shí)體,可以是任何Java對(duì)象。
responseType:響應(yīng)結(jié)果的類(lèi)型,指定要封裝成哪個(gè)Java對(duì)象。
uriVariables:URL中的變量替換值。
3.3、exchange()方法
方法簡(jiǎn)介:
執(zhí)行HTTP請(qǐng)求,并返回ResponseEntity對(duì)象。
方法簽名:
public <T> ResponseEntity<T> exchange(URI url,
HttpMethod method,
HttpEntity<?> requestEntity,
Class<T> responseType,
Object... uriVariables)參數(shù)含義:
url:請(qǐng)求的URL。
method:請(qǐng)求的HTTP方法,如GET、POST等。
requestEntity:請(qǐng)求的實(shí)體,包含請(qǐng)求頭和請(qǐng)求體。
responseType:響應(yīng)結(jié)果的類(lèi)型。
uriVariables:URL中的變量替換值。
3.4、execute()方法
方法簡(jiǎn)介:
執(zhí)行HTTP請(qǐng)求,允許高度定制HTTP請(qǐng)求。
參數(shù)含義:
url:請(qǐng)求的URL,可以是String或URL對(duì)象。
method:HTTP方法,如GET、POST、PUT等。
requestCallback:處理Request的Callback對(duì)象,用于定義Request,如設(shè)置請(qǐng)求頭、查詢(xún)字符串參數(shù)等等。
responseExtractor:處理Response的Callback對(duì)象,用于提取Response內(nèi)容。
3.5、HttpEntity對(duì)象
對(duì)象簡(jiǎn)介:
Spring框架定義的數(shù)據(jù)結(jié)構(gòu),它表示一個(gè)完整的HTTP請(qǐng)求或響應(yīng)。
它主要有兩個(gè)作用:
1、表示HTTP請(qǐng)求:當(dāng)表示HTTP請(qǐng)求時(shí),HttpEntity有兩個(gè)主要組成部分:請(qǐng)求頭和請(qǐng)求體。
2、表示HTTP響應(yīng)當(dāng)表示HTTP響應(yīng)時(shí),有三個(gè)部分:狀態(tài)碼、響應(yīng)頭和響應(yīng)體。
通過(guò)HttpEntity我們可以方便的構(gòu)建和處理HTTP請(qǐng)求和響應(yīng)。
主要參數(shù):
headers:HttpHeaders類(lèi)型,包括所有頭信息。
body:請(qǐng)求或響應(yīng)體,可以是任何對(duì)象。
statusCode:HttpStatus類(lèi)型,只有在表示響應(yīng)時(shí)才有效。
3.6、RequestCallback對(duì)象
RequestCallback是Spring RestTemplate中用來(lái)定制HTTP請(qǐng)求的一個(gè)接口,可以設(shè)置請(qǐng)求頭、請(qǐng)求體、查詢(xún)字符串參數(shù)。Callback接口只有一個(gè)方法:
void doWithRequest(ClientHttpRequest request) throws IOException
在該方法中可以調(diào)用ClientHttpRequest對(duì)象的方法來(lái)定制Request。
如設(shè)置請(qǐng)求頭:
new RequestCallback() {
public void doWithRequest(ClientHttpRequest request) {
request.getHeaders().set("myHeader", "myValue");
}
}設(shè)置請(qǐng)求體:
new RequestCallback() {
public void doWithRequest(ClientHttpRequest request) {
request.getBody()
.write(("some data".getBytes());
}
}設(shè)置查詢(xún)參數(shù):
new RequestCallback() {
public void doWithRequest(ClientHttpRequest request) {
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("param1", "value1");
request.setURI(request.getURI(), map);
}
}四、發(fā)送Get請(qǐng)求
請(qǐng)求層是這樣寫(xiě)的
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/getUserByUsername")
public User getUserById(@RequestParam("username") String username,
@RequestParam("address") String address){
....//業(yè)務(wù)代碼
return user;
}
}這樣寫(xiě)也可以:
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/getUserByUsername")
public User getUserById(User user){
....//業(yè)務(wù)代碼
return user;
}
}4.1、參數(shù)拼接
直接把參數(shù)拼接在url上面:
@Resource
private RestTemplate restTemplate;
public void sendGet(){
String url = "http://localhost:8080/user/getUserByUsername?username=張三&&address=上海";
ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
System.out.println(result.getHeaders());
}執(zhí)行結(jié)果如下:

4.2、占位符傳參
直接在方法中指定參數(shù):
@Resource
private RestTemplate restTemplate;
public void sendGet(){
String url = "http://localhost:8080/user/getUserByUsername?username={name}&address={address}";
ResponseEntity<String> result = restTemplate.getForEntity(url, String.class,"李四","廣東");
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
System.out.println(result.getHeaders());
}執(zhí)行結(jié)果如下:

通過(guò)Map集合傳遞參數(shù),此種方式必須使用占位符,并且map中的key值,要與請(qǐng)求路徑中的占位符一致 :
@Resource
private RestTemplate restTemplate;
public void sendGet(){
String url = "http://localhost:8080/user/getUserByUsername?username={username}&address={address}";
Map<String, Object> map = new HashMap<>();
map.put("username", "李四");
map.put("address", "廣東");
ResponseEntity<String> result = restTemplate.getForEntity(url,String.class,map);
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
System.out.println(result.getHeaders());
}執(zhí)行結(jié)果如下:

4.3、請(qǐng)求頭攜帶Token
定義頭信息:
HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());創(chuàng)建一個(gè)HttpEntity對(duì)象,用于封裝HTTP請(qǐng)求的頭信息:
HttpEntity<Object> entity = new HttpEntity<>(headers);
使用exchange方法發(fā)送Get請(qǐng)求:
ResponseEntity<String> 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<Object> entity = new HttpEntity<>(headers);
ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET,entity, String.class);
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
System.out.println(result.getHeaders());
}執(zhí)行結(jié)果如圖:

4.4、請(qǐng)求頭攜帶Cookie
創(chuàng)建一個(gè)Cookie:
Cookie cookie = new Cookie("cookie", UUID.randomUUID().toString());放入請(qǐng)求頭當(dāng)中 :
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<Object> entity = new HttpEntity<>(headers);
ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET,entity, String.class);
System.out.println(result.getStatusCode());
System.out.println(result.getBody());
System.out.println(result.getHeaders());
}執(zhí)行結(jié)果如圖:

五、發(fā)送Post請(qǐng)求
請(qǐng)求層用到了@RequestBody注解接收參數(shù),具體是這么寫(xiě)的:
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/insert")
public String insertUser(@RequestBody User user){
...//邏輯代碼
return message;
}
}下面進(jìn)行發(fā)送Post請(qǐng)求測(cè)試。
5.1、帶@RequestBody
如果請(qǐng)求層是帶有@RequestBody注解的,可以通過(guò)Json格式進(jìn)行傳參:
@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("無(wú)");
String url = "http://localhost:8080/user/insert";
String result = restTemplate.postForObject(url, user, String.class);
System.out.println(result);
}運(yùn)行結(jié)果如下:

我們也可以通過(guò)Map集合進(jìn)行傳參,效果是一樣的:
@Resource
private RestTemplate restTemplate;
public void sendPost(){
Map<String, Object> 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","無(wú)");
String url = "http://localhost:8080/user/insert";
String result = restTemplate.postForObject(url, map, String.class);
System.out.println(result);
}執(zhí)行結(jié)果如下:

5.2、不帶@RequestBody
如果請(qǐng)求層不帶這個(gè)注解,用上面的兩種方法來(lái)傳遞參數(shù)是獲取不到!
MultiValueMap常用于封裝HTTP請(qǐng)求頭或查詢(xún)參數(shù),它可以同一個(gè)key下面放多個(gè)value,我們也可以通過(guò)MultiValueMap集合來(lái)進(jìn)行傳遞參數(shù):
@Resource
private RestTemplate restTemplate;
public void sendPost(){
MultiValueMap<String, Object> 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","無(wú)");
String url = "http://localhost:8080/user/insert";
String result = restTemplate.postForObject(url, map, String.class);
System.out.println(result);
}運(yùn)行結(jié)果如下:

5.3、請(qǐng)求頭攜帶Token
定義頭信息:
HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());使用HttpEntity把請(qǐng)求對(duì)象user和header進(jìn)行組裝:
HttpEntity<User> 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("無(wú)");
String url = "http://localhost:8080/user/insert";
// 使用 HttpEntity 把請(qǐng)求對(duì)象user 和 header 進(jìn)行組裝
HttpEntity<User> userHttpEntity = new HttpEntity<>(user, headers);
String result = restTemplate.postForObject(url, userHttpEntity, String.class);
System.out.println(result);
}運(yùn)行結(jié)果如下:

六、發(fā)送Put請(qǐng)求
請(qǐng)求層是這么寫(xiě)的:
@RestController
@RequestMapping("/user")
public class UserController {
@PutMapping
public String update(@RequestBody User user){
...//業(yè)務(wù)代碼
return message;
}
}6.1、無(wú)返回值
直接調(diào)用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);
}2、執(zhí)行結(jié)果如下:

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<User> body = new HttpEntity<>(user);
ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.PUT,body,String.class);
System.out.println(result);
}執(zhí)行結(jié)果如圖:

6.3、請(qǐng)求頭攜帶Token
定義頭信息:
HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());使用HttpEntity把請(qǐng)求對(duì)象user和header進(jìn)行組裝,然后調(diào)用exchange方法即可:
HttpEntity<User> body = new HttpEntity<>(user,headers); ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.PUT,body,String.class);
七、發(fā)送Delete請(qǐng)求
請(qǐng)求層是這樣寫(xiě)的:
@RestController
@RequestMapping("/user")
public class UserController {
@DeleteMapping("{id}")
public String delete(@PathVariable String id){
...//業(yè)務(wù)代碼
return message;
}
}7.1、無(wú)返回值
直接調(diào)用delete方式是不帶返回值的:
@Resource
private RestTemplate restTemplate;
public void update(){
String url = "http://localhost:8080/user/{id}";
restTemplate.delete(url,1);
}執(zhí)行結(jié)果如圖:

7.2、有返回值
使用exchange方法執(zhí)行即可,具體代碼如下:
@Resource
private RestTemplate restTemplate;
public void update(){
String url = "http://localhost:8080/user/1";
ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.DELETE,null,String.class);
System.out.println(result);
}執(zhí)行結(jié)果如下:

7.3、請(qǐng)求頭攜帶Token
定義頭信息
HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());使用HttpEntity把請(qǐng)求對(duì)象user和header進(jìn)行組裝,然后調(diào)用exchange方法即可:
HttpEntity<User> body = new HttpEntity<>(headers); ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.DELETE,body,String.class);
八、文件上傳
請(qǐng)求層代碼:
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/upload")
public String upload(MultipartFile file){
return file.getOriginalFilename();
}
}設(shè)置請(qǐng)求頭:
HttpHeaders headers = new HttpHeaders();
headers.add("token", UUID.randomUUID().toString());創(chuàng)建一個(gè)FileSystemResource,將文件封裝為resource:
File file = new File("F:/test.jar");
FileSystemResource resource = new FileSystemResource(file);創(chuàng)建一個(gè)MultiValueMap,將文件添加進(jìn)去,鍵名是"file":
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
multiValueMap.add("file", resource);使用MultiValueMap和headers創(chuàng)建HttpEntity,表示這是個(gè)POST請(qǐng)求,且請(qǐng)求體是文件,發(fā)送POST請(qǐng)求到url,請(qǐng)求體是前面創(chuàng)建的HttpEntity:
HttpEntity< MultiValueMap<String, Object>> request = new HttpEntity<>(multiValueMap, headers); ResponseEntity<String> 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<String, Object> multiValueMap = new LinkedMultiValueMap<>();
multiValueMap.add("file", resource);
HttpEntity< MultiValueMap<String, Object>> request = new HttpEntity<>(multiValueMap, headers);
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
System.out.println(exchange);
}7、執(zhí)行結(jié)果如圖:

九、文件下載
請(qǐng)求層具體是這么寫(xiě)的:
@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());
}
}定義請(qǐng)求頭,申明可以接收所有類(lèi)型的響應(yīng)內(nèi)容:
RequestCallback requestCallback = request -> request.getHeaders()
.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));使用流的方式讀取響應(yīng)內(nèi)容,而不是將響應(yīng)內(nèi)容全部加載到內(nèi)存中 :
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;
});
}執(zhí)行結(jié)果如下:

十、總結(jié)
到此這篇關(guān)于SpringBoot整合RestTemplate用法的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot整合RestTemplate內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot統(tǒng)一返回JSON格式實(shí)現(xiàn)方法詳解
這篇文章主要介紹了SpringBoot統(tǒng)一返回JSON格式實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-02-02
SpringBoot整合Lombok及常見(jiàn)問(wèn)題解決
本文主要介紹了SpringBoot整合Lombok及常見(jiàn)問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
SpringBoot整合Flyway的方法(數(shù)據(jù)庫(kù)版本遷移工具)
這篇文章主要介紹了SpringBoot整合Flyway的方法(數(shù)據(jù)庫(kù)版本遷移工具),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
SpringBoot如何配置文件給bean賦值問(wèn)題
關(guān)于springboot2整合lettuce啟動(dòng)卡住問(wèn)題的解決方法
java計(jì)算值所占的百分比,結(jié)果為100%問(wèn)題
SpringBoot實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)的項(xiàng)目實(shí)戰(zhàn)

