SpringBoot圖文教程17—上手就會 RestTemplate 使用指南「Get Post」「設置請求頭」
- 2020 年 3 月 30 日
- 筆記
問個問題:通過Java程式碼怎麼發送Http請求,請求另一個Java程式的Controller方法呢?

好像真的有點觸及到知識盲區了呦
在以前的程式碼中,Java程式都是被請求的一方,發送請求的要麼是Ajax,要麼是瀏覽器,要麼是postman等,今天就來一起學習一下如何通過Java程式碼發送Http請求。
RestTemplate 的使用

準備工作「可以跳過,不影響教程學習」
因為我們要通過RestTemplate發送請求,請求另外一個項目的Controller層方法(介面),所以我們首先需要一個被請求的項目。 關於這個項目,我已經搭建好了,碼雲地址為:https://gitee.com/bingqilinpeishenme/boot-demo/tree/master/boot-base-rest
在項目中有三個方法,分別是測試Get請求和Post請求如下
package com.lby.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /** * @author luxiaoyang * @create 2020-03-18-20:02 */ @Controller public class TestController { /** * @GetMapping("testRestGet") 當前方法只接受Get請求 * 等價於 * @RequestMapping(path = "testRestGet",method = RequestMethod.GET) */ @GetMapping("testRestGet") @ResponseBody public String testRestGet(String username){ return "這是一個Get請求,接受參數:"+username; } /** * @PostMapping("") 當前方法只接受Post請求 * 等價於 * @RequestMapping(path = "testRestPost",method = RequestMethod.POST) */ @PostMapping("testRestPost") @ResponseBody public String testRestPost(String username){ return "這是一個Post請求,接受參數:"+username; } /** * 測試 postForLocation 給RestTemplate響應url地址 */ @PostMapping("testRestPostLocation") public String testRestPostLocation(String username){ System.out.println(username); return "redirect:/success.html"; } }
什麼是RestTemplate
Spring中封裝的通過Java程式碼發送RestFul請求的模板類,內置發送get post delete等請求的方法,在SpringBoot中只要導入spring-boot-starter-web的依賴可以直接使用。
快速開始
確定項目中導入spring-boot-starter-web的依賴。
第一步:配置RestTemplate

/** * RestTemplate配置 */ @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory) { return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); // 超時設置 factory.setReadTimeout(5000);//ms factory.setConnectTimeout(15000);//ms return factory; } }
第二步:直接使用RestTemplate的Api發送請求
這一步,我們直接在測試類中發送Get方式的請求,進行簡單的測試,感受到效果之後,再進行更多API深入的學習。
package com.lby; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestTemplate; @RunWith(SpringRunner.class) @SpringBootTest(classes = {BootResttemplateApplication.class}) public class BootResttemplateApplicationTests { @Autowired private RestTemplate restTemplate; /** * 測試get請求 */ @Test public void test1(){ /** * getForObject * * 參數1 要請求的地址的url 必填項 * 參數2 響應數據的類型 是String 還是 Map等 必填項 * 參數3 請求攜帶參數 選填 * * getForObject 方法的返回值就是 被調用介面響應的數據 */ String result = restTemplate.getForObject("http://localhost:8802/product/showProductById?id=1", String.class); System.out.println(result); } }
RestTemplate的主要API
HTTP Method |
RestTemplate Methods |
---|---|
Get |
getForObject, getForEntity |
Post |
postForEntity, postForObject, postForLocation |
PUT |
put |
any |
exchange, execute |
DELETE |
delete |
HEAD |
headForHeaders |
OPTIONS |
optionsForAllow |
以上是RestTemplate的主要API,其中大部分的API會在後續的程式碼中詳細講解。
Get請求的所有使用方式
Get請求方式:
- url拼接參數
- url拼接參數「佔位符的方式」
- 獲取響應實體對象「響應狀態碼」
/** * 測試get請求 */ @Test public void test1(){ /** * getForObject * * 參數1 要請求的地址的url 必填項 * 參數2 響應數據的類型 是String 還是 Map等 必填項 * 參數3 請求攜帶參數 選填 * * getForObject 方法的返回值就是 被調用介面響應的數據 */ String result = restTemplate.getForObject("http://localhost:8802/testRestGet?username=zhangsan", String.class); System.out.println(result); /** * getForEntity 方法 * 參數1 要請求的地址的url 必填項 * 參數2 響應數據的類型 是String 還是 Map等 必填項 * 參數3 請求攜帶參數 選填 * * 返回值類型為 ResponseEntity * * 可以通過ResponseEntity 獲取響應的數據,響應的狀態碼等資訊 */ ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8802/testRestGet?username=zhangsan", String.class); System.out.println("獲取響應的狀態:"+responseEntity.getStatusCode()); System.out.println("獲取響應的數據:"+responseEntity.getBody()); /** * 通過Map傳參 */ Map map= new HashMap(); map.put("name","zhangsan"); String resultId = restTemplate.getForObject("http://localhost:8802/testRestGet?username={name}", String.class,map); System.out.println(resultId); }
需要注意的是通過Map方式傳參

執行測試類程式碼,可以看到如下效果:

Post請求的所有使用方式
post請求三種情況
- 模擬攜帶表單參數
- url拼接參數
- 請求成功之後,獲取跳轉地址
/** * 測試Post請求 */ @Test public void test2(){ /** * postForObject 返回值為響應的數據 * 參數1 要請求地址的url * 參數2 通過LinkedMultiValueMap對象封裝請求參數 模擬表單參數,封裝在請求體中 * 參數3 響應數據的類型 */ LinkedMultiValueMap<String, String> request = new LinkedMultiValueMap<>(); request.set("username","zhangsan"); String result = restTemplate.postForObject("http://localhost:8802/testRestPost",request,String.class); System.out.println(result); /** * Post請求的時候同樣也可以進行參數拼接,使用方式和Get一樣 * 示例如下,通過map封裝數據,利用佔位符的方式可以將參數拼接到url上 * 和Get請求url拼接一樣 */ Map map = new HashMap(); map.put("password","123456"); String result2 = restTemplate.postForObject("http://localhost:8802/testRestPost?password={password}",request, String.class,map); /** * postForLocation 這個API和前兩個都不一樣 * * 登錄or註冊都是post請求,而這些操作完成之後呢?大部分都是跳轉到別的頁面去了,這種場景下,就可以使用 postForLocation 了,提交數據,並獲取返回的URI * 響應參數要跳轉的地址 */ URI uri = restTemplate.postForLocation("http://localhost:8802/testRestPostLocation", request); System.out.println("postForLocation請求到的地址為:"+uri); }
執行測試方法,效果如下:

Tips:delete,put等請求方式的使用類似Get和Post,模仿Get和Post 即可搞定。
Get和Post如何設置請求頭
通用方式設置請求頭「適合Get,Post等請求」
1.創建ClientHttpRequestInterceptor類,添加請求頭
package com.lby; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import java.io.IOException; /** * @author luxiaoyang * @create 2020-03-20-20:37 */ public class UserAgentInterceptor implements ClientHttpRequestInterceptor { @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { HttpHeaders headers = request.getHeaders(); // 設置請求頭參數 headers.add(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"); return execution.execute(request, body); } }
2.在Get請求的時候,使用請求頭
/** * 通用方式設置請求頭 */ @Test public void test3(){ /** * RestTemplate設置使用請求頭的攔截器 */ restTemplate.setInterceptors(Collections.singletonList(new UserAgentInterceptor())); /** * 正常的發送請求 */ String result = restTemplate.getForObject("http://localhost:8802/testRestGet?username=zhangsan", String.class); System.out.println(result); }
Post請求設置請求頭的第二種方式
Post請求的第二個參數是Request,可以根據請求頭 + 請求參數,構建 HttpEntity 對象,將這個作為post的請求request參數傳入。具體的程式碼如下:
/** * Post方式設置請求頭 */ @Test public void test4(){ //1. 設置請求頭參數 HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"); //2. 模擬表單參數 請求體攜帶參數 MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>(); requestBody.add("username", "zhangsan"); //3. 封裝HttpEntity對象 HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, requestHeaders); RestTemplate restTemplate = new RestTemplate(); //4. 發送Post請求 ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost:8802/testRestPost", requestEntity, String.class); System.out.println(responseEntity.getBody()); }
總結
所有示例程式碼下載地址:https://gitee.com/bingqilinpeishenme/boot-demo/tree/master 恭喜你完成了本章的學習,為你鼓掌!如果本文對你有幫助,請幫忙點贊,評論,轉發,這對作者很重要,謝謝。

讓我們再次回顧本文的學習目標
- 掌握SpringBoot中RestTemplate的使用
要掌握SpringBoot更多的用法,請持續關注本系列教程。