什么是 RestClient

RestClient 是 Spring Framework 6.1 引入的一个同步 HTTP 客户端,旨在替代传统的 RestTemplate。它提供了更简洁、现代的 API 设计,专注于同步请求场景,支持链式调用(Fluent API),并能够与 Spring 生态(如错误处理、拦截器等)无缝集成。

适用版本:本文内容适用于 Spring Framework 6.1+Spring Boot 3.2+

核心特性

  • 同步请求:专为传统阻塞式调用场景设计,线程模型简单直观。
  • 链式调用:采用 Fluent API 风格,代码结构更清晰,可读性更强。
  • 灵活配置:支持自定义请求头、拦截器、错误处理策略等。
  • 生态集成:可直接作为 Bean 注入,或复用 RestTemplate 的相关组件(如 HttpMessageConverter)。

依赖配置

确保项目使用 Spring Boot 3.2+,或手动引入 spring-web 6.1+。在 Spring Boot 项目中,通常无需指定版本号,由父工程管理依赖。

<!-- Maven 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- Spring Boot 3.2+ 默认包含 Spring Framework 6.1+ -->
</dependency>

快速使用示例

1. 创建 RestClient 实例

通过 Builder 模式进行基础配置,包括基础 URL 和默认请求头。

import org.springframework.web.client.RestClient;

// 基础配置
RestClient client = RestClient.builder()
    .baseUrl("https://api.example.com")           // 设置基础 URL
    .defaultHeader("Accept", "application/json")  // 设置默认请求头
    .build();

2. 发起 GET 请求

获取 JSON 响应并自动反序列化为 Java 对象。

// 获取 JSON 响应并反序列化为对象
User user = client.get()
    .uri("/users/{id}", 1)   // 设置 URI 及路径变量
    .retrieve()              // 发起请求并准备提取响应
    .body(User.class);       // 将响应体反序列化为 User 对象

System.out.println(user.getName());

3. 发起 POST 请求

提交 JSON 数据到服务器,并接收创建后的资源信息。

// 提交 JSON 数据
User newUser = new User("Alice", 30);
User createdUser = client.post()
    .uri("/users")
    .contentType(MediaType.APPLICATION_JSON)
    .body(newUser)           // 设置请求体
    .retrieve()
    .body(User.class);

4. 处理错误

自定义状态码处理逻辑,针对特定 HTTP 状态抛出业务异常。

// 自定义错误处理
client.get()
    .uri("/users/{id}", 999)
    .retrieve()
    .onStatus(status -> status.value() == 404, (req, res) -> {
        throw new UserNotFoundException("User not found");
    })
    .body(User.class);

高级功能

1. 添加拦截器

通过拦截器统一处理认证头或其他跨切面逻辑。

RestClient client = RestClient.builder()
    .baseUrl("https://api.example.com")
    .requestInterceptor(headers -> {
        // 添加认证头
        headers.set("Authorization", "Bearer token");
    })
    .build();

2. 自定义消息转换器

注册或自定义 HTTP 消息转换器,以支持特殊的数据格式序列化与反序列化。

RestClient client = RestClient.builder()
    .messageConverters(converters -> {
        converters.add(new MappingJackson2HttpMessageConverter());
        converters.add(new StringHttpMessageConverter());
    })
    .build();

3. 文件下载

处理二进制流响应,例如下载 PDF 或图片文件。

client.get()
    .uri("/files/{name}", "report.pdf")
    .accept(MediaType.APPLICATION_PDF)
    .retrieve()
    .body(InputStreamResource.class);  // 获取文件输入流资源

与旧组件的对比

特性RestClient (6.1+)RestTemplate (旧)WebClient (响应式)
请求类型同步同步异步/非阻塞
API 设计链式调用 (Fluent)传统方法调用链式调用 + Reactor
适用场景简单同步 HTTP 调用旧项目兼容维护响应式或复杂异步场景
主要依赖spring-webspring-webspring-webflux

总结

  • 推荐场景:在 Spring 6.1+ 及 Spring Boot 3.2+ 的新项目中,优先使用 RestClient 替代 RestTemplate
  • 核心优势:语法简洁直观、易于扩展、与 Spring 生态深度集成。
  • 注意事项RestClient 专注于同步阻塞场景;如果需要异步或响应式编程模型,请继续使用 WebClient
说明:本文示例基于 Spring Framework 6.1 及 Spring Boot 3.2 版本编写。若使用更低版本,部分 API 可能不可用,请升级框架版本或沿用 RestTemplate