SpringBoot整合RestTemplate用法的實(shí)現(xiàn)
前言:本篇主要介紹了RestTemplate中的GET,POST,PUT,DELETE、文件上傳和文件下載6大常用的功能,每一個(gè)方法和每一行代碼都進(jìn)行了詳細(xì)的講解,代碼都是親自測(cè)試過的,整篇博客寫完以后自己也是受益匪淺,于是在這做個(gè)技術(shù)分享!
一、RestTemplate簡(jiǎn)介
RestTemplate是Spring框架用來訪問RESTFUL服務(wù)的客戶端模板類,主要功能有:
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ì)不同的輸入/輸出類型提供對(duì)應(yīng)的方法,如字符串、對(duì)象、多部分等。
5、支持遠(yuǎn)程調(diào)用,不受同源策略限制。
二、基礎(chǔ)配置
2.1、先導(dǎo)入pom.xml依賴
<dependencies> <!-- RestTemplate需要的依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Lombok依賴 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- 單元測(cè)試依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.2、創(chuàng)建RestTemplateConfig配置類
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
2.3、User實(shí)體類
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é)果的類型。指定要封裝成哪個(gè)Java對(duì)象,它可以是POJO或者任何Java類型。
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é)果的類型,指定要封裝成哪個(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é)果的類型。
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)求頭、查詢字符串參數(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)體。
通過HttpEntity我們可以方便的構(gòu)建和處理HTTP請(qǐng)求和響應(yīng)。
主要參數(shù):
headers:HttpHeaders類型,包括所有頭信息。
body:請(qǐng)求或響應(yīng)體,可以是任何對(duì)象。
statusCode:HttpStatus類型,只有在表示響應(yīng)時(shí)才有效。
3.6、RequestCallback對(duì)象
RequestCallback是Spring RestTemplate中用來定制HTTP請(qǐng)求的一個(gè)接口,可以設(shè)置請(qǐng)求頭、請(qǐng)求體、查詢字符串參數(shù)。Callback接口只有一個(gè)方法:
void doWithRequest(ClientHttpRequest request) throws IOException
在該方法中可以調(diào)用ClientHttpRequest對(duì)象的方法來定制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è)置查詢參數(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)求層是這樣寫的
@RestController @RequestMapping("/user") public class UserController { @GetMapping("/getUserByUsername") public User getUserById(@RequestParam("username") String username, @RequestParam("address") String address){ ....//業(yè)務(wù)代碼 return user; } }
這樣寫也可以:
@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é)果如下:
通過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ù),具體是這么寫的:
@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注解的,可以通過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("無"); String url = "http://localhost:8080/user/insert"; String result = restTemplate.postForObject(url, user, String.class); System.out.println(result); }
運(yùn)行結(jié)果如下:
我們也可以通過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","無"); 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è)注解,用上面的兩種方法來傳遞參數(shù)是獲取不到!
MultiValueMap常用于封裝HTTP請(qǐng)求頭或查詢參數(shù),它可以同一個(gè)key下面放多個(gè)value,我們也可以通過MultiValueMap集合來進(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","無"); 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("無"); 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)求層是這么寫的:
@RestController @RequestMapping("/user") public class UserController { @PutMapping public String update(@RequestBody User user){ ...//業(yè)務(wù)代碼 return message; } }
6.1、無返回值
直接調(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)求層是這樣寫的:
@RestController @RequestMapping("/user") public class UserController { @DeleteMapping("{id}") public String delete(@PathVariable String id){ ...//業(yè)務(wù)代碼 return message; } }
7.1、無返回值
直接調(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)求層具體是這么寫的:
@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)求頭,申明可以接收所有類型的響應(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)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02SpringBoot整合Flyway的方法(數(shù)據(jù)庫(kù)版本遷移工具)
這篇文章主要介紹了SpringBoot整合Flyway的方法(數(shù)據(jù)庫(kù)版本遷移工具),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06

關(guān)于springboot2整合lettuce啟動(dòng)卡住問題的解決方法

java計(jì)算值所占的百分比,結(jié)果為100%問題

SpringBoot實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)的項(xiàng)目實(shí)戰(zhàn)