關於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}¶m2={2}", String.class,map);
- 也可以直接將要傳遞的值放到getForObject方法的參數結尾,數量不限,它會按順序替換{1}和{2}
String result = restTemplate.getForObject("http://localhost:8081/server?param1={1}¶m2={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}¶m2={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 = 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;
}