spring boot2 (25)-RestTemplate客戶端

關於rest可參考第3篇,而RestTemplate就是由spring提供的,用於在後臺進行rest請求的,比繁瑣的HttpClient要方便很多。

pom.xml

從本篇開始,後續文章都使用spring boot2,要求jdk版本至少8。之前的文章仍然適用於低版本的jdk,繼續保留。spring boot 1和2大部分用法是一樣的,只是有些功能做了細節調整。如默認連接池從tomcat變成了HikariCP,actuator有較大改動等。
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>

rest服務端

先創建一個服務端項目,項目中有一個接口方法提供服務,如下。端口爲8081,啓動項目

@RestController
public class HelloController {
	
	@RequestMapping("/server")
	public String server() {
		return "hello";
	}
}

rest客戶端

創建客戶端項目,在配置類中,使用RestTemplateBuilder來構建一個RestTemplate。

	@Autowired
	RestTemplateBuilder restTemplateBuilder;
	//在配置類中使用restTemplateBuilder構建RestTemplate實例
	@Bean
	public RestTemplate restTemplate(){
		return restTemplateBuilder.build();
	}

在控制層使用restTemplate來訪問服務端,客戶端端口爲8080,啓動項目

@RestController
public class ClientController {
	@Autowired
	RestTemplate restTemplate;
	
	@RequestMapping("/client")
	public String client() {
		//通過restTemplate請求rest服務端
		String result = restTemplate.getForObject("http://localhost:8081/server", String.class);
		return result;
	}

getForObject方法

getForObject指get請求,並返回一個Object對象。這裏有2個方法參數

  • 第1個參數:請求的url地址
  • 第2個參數:返回的結果類型,這裏String.class表示返回結果是一個字符串。

運行結果


如圖,通過瀏覽器請求http://localhost:8080/client,客戶端又通過restTemplate請求了服務端的數據hello,最終返回。

請求參數

  • 可以使用map來封裝請求參數,並作爲getForObject的第三個參數,同時修改url如下,map中的"1"會替換url中的{1},"2"會替換url中的{2}
		Map map = new HashMap();
		map.put("1", "hello");
		map.put("2", "world");
		String result = restTemplate.getForObject("http://localhost:8081/server?param1={1}&param2={2}", String.class,map);
  • 也可以直接將要傳遞的值放到getForObject方法的參數結尾,數量不限,它會按順序替換{1}和{2}
String result = restTemplate.getForObject("http://localhost:8081/server?param1={1}&param2={2}", String.class, "hello", "world");

getForEntity方法

getForEntity和getForObject的用法是一樣的,只是其返回結果是一個ResponseEntity,其中包含了更多的響應信息,比如:

		ResponseEntity response = restTemplate.getForEntity("http://localhost:8081/server",String.class);
		response.getHeaders();		//響應頭
		response.getStatusCode();	//響應碼
		response.getBody();			//響應體,即前面的result

postForObject方法

postForObject指post請求,並返回一個Object對象。

String response = restTemplate.postForObject("http://localhost:8081/server?param1={1}&param2={2}", null, String.class, "hello", "world");
  • postForObject第1個參數就是getForObject第1個參數。
  • postForObject第3個參數就是getForObject第2個參數。
  • postForObject第4個及以後的參數就是getForObject第3個及以後的參數。

postForObject除了第2個參數爲null,其它地方用法和getForObject是一模一樣的。但是post請求傳參通常不是寫在url上實現的,而是放在請求體中。此時,就需要使用第2個參數來傳參,同時可省略第4個參數的url傳參,如下

		Map map = new HashMap();
		map.put("param1", "hello");
		map.put("param2", "world");
		String response = restTemplate.postForObject("http://localhost:8081/server", map, String.class);
注意,服務端端接收不同參數時,語法也有所不同,如下
public String server(@RequestBody Map map,String param1,String param2)
  • @RequestBody Map map:此註解可用於接收請求體,即postForObject的第2個map參數。此註解第3篇有講過。
  • String param1,String param2:用於接收postForObject第4個及以後參數的url傳參 。

HttpEntity

postForObject的第2個參數其實是HttpEntity,這個類主要有三種構造方法,如下

  • new HttpEntity(請求體)
  • new HttpEntity(請求頭)
  • new HttpEntity(請求體,請求頭)
當我前面傳了一個map參數時,系統內部會自動使用第一種方法,將這個map作爲請求體,並封裝成HttpEntity。以下以第三種方法爲例,介紹如何使用HttpEntity同時發送請求體和請求頭:
		//請求體
		Map map = new HashMap();
		map.put("param1", "hello");
		map.put("param2", "world");
		//請求頭
		MultiValueMap headers = new HttpHeaders();
		headers.add("Accept", "text/xml");
		//請求內容封裝成httpEntity
		HttpEntity httpEntity= new HttpEntity(map,headers);
		
		restTemplate.postForObject("http://localhost:8081/server", httpEntity, String.class);

postForEntity

和getForEntity原理是一樣的

配置超時

如果要設置請求的超時時間,可修改前面restTemplate的構建代碼,如下

	@Bean
	public RestTemplate restTemplate(){
		RestTemplate restTemplate = restTemplateBuilder
			.setConnectTimeout(1000)		//連接超時爲1秒
			.setReadTimeout(1000)			//請求超時爲1秒
			.build();
		return restTemplate;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章