RestTemplate 全面详解及示例
1. RestTemplate 简介
-
定义:Spring 提供的同步 HTTP 客户端,支持多种 HTTP 方法(GET/POST/PUT/DELETE 等),用于调用 RESTful API。
-
核心特性 :
- 支持请求头、请求体、URI 参数的灵活配置。
- 可直接返回
ResponseEntity
获取状态码和响应头。 - 支持对象序列化(如 JSON)和反序列化。
-
依赖 (Spring Boot 项目):
xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. 示例代码详解
示例 1:GET 请求(带请求头,获取状态码和响应头)
java
// 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 请求体)
java
// 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 请求(更新资源)
java
// 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 请求
java
// 发送 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)
java
// 将响应体反序列化为 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 定制响应
java
// 自定义提取器:提取响应体中的某个字段
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:批量操作(查询多个资源)
java
// 使用 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. 关键配置与注意事项
-
设置连接池(提升性能):
javaRestTemplate restTemplate = new RestTemplate( new HttpClientErrorException.Factory(), new HttpComponentsClientHttpRequestFactory() );
-
异常处理:
javatry { // 发送请求 } catch (HttpClientErrorException e) { System.out.println("Client error: " + e.getStatusCode()); } catch (HttpServerErrorException e) { System.out.println("Server error: " + e.getStatusCode()); }
-
自定义序列化器:
javaObjectMapper 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 的全场景调用需求。