有天上飛的概念,就要有落地的實現html
概念十遍不如代碼一遍,朋友,但願你把文中全部的代碼案例都敲一遍java
先贊後看,養成習慣git
SpringBoot 圖文教程系列文章目錄web
問個問題:經過Java代碼怎麼發送Http請求,請求另外一個Java程序的Controller方法呢?面試
好像真的有點觸及到知識盲區了呦spring
在之前的代碼中,Java程序都是被請求的一方,發送請求的要麼是Ajax,要麼是瀏覽器,要麼是postman等,今天就來一塊兒學習一下如何經過Java代碼發送Http請求。api
由於咱們要經過RestTemplate發送請求,請求另一個項目的Controller層方法(接口),因此咱們首先須要一個被請求的項目。
關於這個項目,我已經搭建好了,碼雲地址爲:https://gitee.com/bingqilinpeishenme/boot-demo/tree/master/boot-base-rest瀏覽器
在項目中有三個方法,分別是測試Get請求和Post請求以下app
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"; } }
Spring中封裝的經過Java代碼發送RestFul請求的模板類,內置發送get post delete等請求的方法,在SpringBoot中只要導入spring-boot-starter-web的依賴能夠直接使用。ide
肯定項目中導入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); } }
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請求 */ @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請求 */ @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 便可搞定。
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請求的第二個參數是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更多的用法,請持續關注本系列教程。
歡迎關注本人公衆號:鹿老師的Java筆記,將在長期更新Java技術圖文教程和視頻教程,Java學習經驗,Java面試經驗以及Java實戰開發經驗。