spring mvc 中 RestTemplate 全面详解及示例


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. 关键配置与注意事项
  • 设置连接池(提升性能):

    java 复制代码
    RestTemplate restTemplate = new RestTemplate(
        new HttpClientErrorException.Factory(),
        new HttpComponentsClientHttpRequestFactory()
    );
  • 异常处理

    java 复制代码
    try {
        // 发送请求
    } catch (HttpClientErrorException e) {
        System.out.println("Client error: " + e.getStatusCode());
    } catch (HttpServerErrorException e) {
        System.out.println("Server error: " + e.getStatusCode());
    }
  • 自定义序列化器

    java 复制代码
    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); 简化复杂响应处理逻辑

关键总结

  1. 核心类
    • RestTemplate:核心客户端,提供所有 HTTP 方法。
    • HttpEntity:封装请求头和请求体。
    • ResponseEntity:封装响应头、状态码和响应体。
  2. 最佳实践
    • 使用 exchange 方法统一处理复杂场景。
    • 通过 ResponseEntity 获取完整响应信息。
    • 自定义 HttpMessageConverter 处理特殊序列化需求。
  3. 替代方案
    Spring Boot 3.x 已弃用 RestTemplate,推荐使用 WebClient(响应式、非阻塞)。

通过以上示例和配置,开发者可以灵活实现 REST API 的全场景调用需求。

相关推荐
风象南3 分钟前
SpringBoot中3种应用事件处理机制
java·spring boot·后端
我有医保我先冲3 分钟前
C++笔记
java·c++·笔记
helloworld工程师1 小时前
Spring AI应用:利用DeepSeek+嵌入模型+Milvus向量数据库实现检索增强生成--RAG应用(超详细)
人工智能·spring·milvus
我命由我123452 小时前
35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)
java·服务器·开发语言·jvm·后端·架构·java-ee
CopyLower3 小时前
分布式ID生成方案的深度解析与Java实现
java·开发语言·分布式
_zsw5 小时前
Spring三级缓存学习
学习·spring·缓存
m0_684598536 小时前
如何开发英语在线训练小程序:从0到1的详细步骤
java·微信小程序·小程序·小程序开发
ml130185288746 小时前
开发一个环保回收小程序需要哪些功能?环保回收小程序
java·大数据·微信小程序·小程序·开源软件
Charlie__ZS6 小时前
SpringCloud - 分布式事务
分布式·spring·spring cloud
zybishe7 小时前
免费送源码:Java+ssm+MySQL 酒店预订管理系统的设计与实现 计算机毕业设计原创定制
java·大数据·python·mysql·微信小程序·php·课程设计