RestTemplate 全面詳解及示例
1. RestTemplate 簡介
- 定義:Spring 提供的同步 HTTP 客戶端,支持多種 HTTP 方法(GET/POST/PUT/DELETE 等),用于調用 RESTful API。
- 核心特性:
- 支持請求頭、請求體、URI 參數的靈活配置。
- 可直接返回
ResponseEntity
獲取狀態碼和響應頭。 - 支持對象序列化(如 JSON)和反序列化。
- 依賴(Spring Boot 項目):
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>
2. 示例代碼詳解
示例 1:GET 請求(帶請求頭,獲取狀態碼和響應頭)
// 1. 創建 RestTemplate 實例
RestTemplate restTemplate = new RestTemplate();// 2. 構建請求 URI(包含路徑參數)
String uri = "http://api.example.com/users/{id}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("id", "123");// 3. 設置請求頭
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer token_123");
headers.setContentType(MediaType.APPLICATION_JSON);// 4. 發送 GET 請求并獲取 ResponseEntity
ResponseEntity<User> response = restTemplate.exchange(uri,HttpMethod.GET,new HttpEntity<>(headers), // 請求體為空,僅傳遞頭User.class, // 響應體反序列化類型uriVariables
);// 5. 處理響應
int statusCode = response.getStatusCodeValue(); // 獲取狀態碼
HttpHeaders responseHeaders = response.getHeaders(); // 獲取響應頭
User user = response.getBody(); // 獲取響應體對象
示例 2:POST 請求(傳遞 JSON 請求體)
// 1. 創建請求體對象(使用 Jackson 自動序列化)
User newUser = new User("John", 25);// 2. 構建請求頭
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);// 3. 創建 HttpEntity(包含頭和請求體)
HttpEntity<User> request = new HttpEntity<>(newUser, headers);// 4. 發送 POST 請求
ResponseEntity<String> response = restTemplate.postForEntity("http://api.example.com/users",request,String.class // 返回的響應類型(如成功返回 "Created")
);// 5. 處理響應
String locationHeader = response.getHeaders().getFirst("Location"); // 獲取 Location 頭
示例 3:PUT/PATCH 請求(更新資源)
// 1. 更新對象
User updatedUser = new User("John Doe", 26);// 2. 構建請求頭和請求體
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<User> request = new HttpEntity<>(updatedUser, headers);// 3. 發送 PUT 請求
ResponseEntity<Void> response = restTemplate.exchange("http://api.example.com/users/123",HttpMethod.PUT,request,Void.class // 無響應體時使用 Void
);// 4. 檢查狀態碼
if (response.getStatusCode() == HttpStatus.OK) {System.out.println("Update successful");
}
示例 4:DELETE 請求
// 發送 DELETE 請求
ResponseEntity<Void> response = restTemplate.exchange("http://api.example.com/users/123",HttpMethod.DELETE,null, // 無請求體Void.class
);if (response.getStatusCode() == HttpStatus.NO_CONTENT) {System.out.println("Resource deleted");
}
示例 5:自定義響應類型(如 Map)
// 將響應體反序列化為 Map
ResponseEntity<Map<String, Object>> response = restTemplate.getForEntity("http://api.example.com/data",new ParameterizedTypeReference<Map<String, Object>>() {}
);Map<String, Object> data = response.getBody();
示例 6:使用 ResponseExtractor 定制響應
// 自定義提取器:提取響應體中的某個字段
ResponseExtractor<String> extractor = response -> {if (response.getStatusCode() == HttpStatus.OK) {return response.getHeaders().getFirst("X-Custom-Header"); // 提取自定義頭}return null;
};// 使用 exchange 方法
String customHeader = restTemplate.exchange("http://api.example.com/headers",HttpMethod.GET,null,extractor // 傳遞自定義提取器
);
示例 7:批量操作(查詢多個資源)
// 使用 UriComponentsBuilder 構建帶查詢參數的 URI
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://api.example.com/users").queryParam("page", 1).queryParam("size", 10);// 發送 GET 請求并獲取列表
ResponseEntity<User[]> response = restTemplate.getForEntity(builder.toUriString(),User[].class
);User[] users = response.getBody();
3. 核心方法對比表格
方法 | HTTP 方法 | 返回類型 | 關鍵代碼片段 | 適用場景 |
---|---|---|---|---|
getForObject | GET | 對象(如 User) | restTemplate.getForObject(url, User.class); | 簡單 GET 請求,直接返回對象 |
getForEntity | GET | ResponseEntity<User> | restTemplate.getForEntity(url, User.class); | 需獲取狀態碼或響應頭 |
postForObject | POST | 對象(如 String) | restTemplate.postForObject(url, request, String.class); | POST 請求,直接返回結果 |
postForEntity | POST | ResponseEntity<Void> | restTemplate.postForEntity(url, request, Void.class); | 需檢查狀態碼或 Location 頭 |
exchange | 任意方法 | ResponseEntity<?> | restTemplate.exchange(url, HttpMethod.POST, request, Class<T>); | 自定義 HTTP 方法和響應類型 |
delete | DELETE | void | restTemplate.delete(url); | 簡單刪除操作 |
4. 關鍵配置與注意事項
-
設置連接池(提升性能):
RestTemplate restTemplate = new RestTemplate(new HttpClientErrorException.Factory(),new HttpComponentsClientHttpRequestFactory() );
-
異常處理:
try {// 發送請求 } catch (HttpClientErrorException e) {System.out.println("Client error: " + e.getStatusCode()); } catch (HttpServerErrorException e) {System.out.println("Server error: " + e.getStatusCode()); }
-
自定義序列化器:
ObjectMapper objectMapper = new ObjectMapper(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(objectMapper); restTemplate.getMessageConverters().add(converter);
5. 總結對比表格
需求 | 實現方法 | 關鍵代碼 | 注意事項 |
---|---|---|---|
發送 JSON 請求體 | 使用 HttpEntity<User> 或 HttpEntity<String> | HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); | 確保序列化配置正確 |
獲取狀態碼和響應頭 | 返回 ResponseEntity<T> | response.getStatusCode(); response.getHeaders(); | 處理 2xx/4xx/5xx 狀態碼 |
自定義響應類型 | 使用 ParameterizedTypeReference 或泛型 | new ParameterizedTypeReference<List<User>>() {} | 處理復雜泛型類型 |
響應提取器 | 實現 ResponseExtractor 接口或使用預定義提取器 | restTemplate.exchange(url, HttpMethod.GET, null, extractor); | 簡化復雜響應處理邏輯 |
關鍵總結
- 核心類:
RestTemplate
:核心客戶端,提供所有 HTTP 方法。HttpEntity
:封裝請求頭和請求體。ResponseEntity
:封裝響應頭、狀態碼和響應體。
- 最佳實踐:
- 使用
exchange
方法統一處理復雜場景。 - 通過
ResponseEntity
獲取完整響應信息。 - 自定義
HttpMessageConverter
處理特殊序列化需求。
- 使用
- 替代方案:
Spring Boot 3.x 已棄用RestTemplate
,推薦使用 WebClient(響應式、非阻塞)。
通過以上示例和配置,開發者可以靈活實現 REST API 的全場景調用需求。