Files
blog-press/docs/Web/SpringBoot/SpringBoot-RestClient.md
2026-05-20 11:26:38 +08:00

4.2 KiB
Raw Blame History

title, date
title date
SpringBoot RestClient简介 2026-01-06

一、简介

RestClient 是 Spring Framework 6.1(及对应的 Spring Boot 3.2+)推出的新一代同步 HTTP 客户端,设计目标是替代传统的 RestTemplateSpring 已标记 RestTemplate 为维护模式,不再新增功能),同时结合了 WebClient 的流畅 API 设计,又保持了 RestTemplate 的同步、简单易用的特点。

二、使用

2.1 创建实例

@Configuration
public class RestClientConfig {
    final String baseUrl = "https://demo.com";

    @Bean
    public RestClient restClient() {

        return RestClient.builder()
                // 基础RURL
                .baseUrl(baseUrl)  
                // 默认请求头 请求体为JSON格式
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                // 默认请求头 响应体为JSON格式
                .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .build();
    }
}

2.2 HTTP请求

@Service
public class RestClientService {

    @Resource
    private RestClient restClient;

    // 1. GET 请求:获取单个资源
    public Post getPostById(Long id) {
        return restClient.get() // 指定 GET 方法
                .uri("/posts/{id}", id) // 请求路径(支持路径参数)
                .retrieve() // 执行请求并获取响应
                .body(Post.class); // 解析响应体为Post实体
    }

    // 2. GET 请求:获取列表并解析为 Map
    public Map<String, Object>[] getAllPosts() {
        return restClient.get()
                .uri("/posts")
                .retrieve()
                .body(Map[].class); // 解析为 Map 数组(适合未知结构的 JSON
    }

    // 3. POST 请求:提交数据并获取响应
    public Boolean createPost(Post post) {
        return restClient.post() // 指定 POST 方法
                .uri("/posts")
                .body(post) // 设置请求体
                .retrieve()
                .body(Boolean.class);
    }

    // 4. PUT 请求:更新资源
    public Boolean updatePost(Long id, Post post) {
        return restClient.put() // 指定 PUT 方法
                .uri("/posts/{id}", id)
                .body(post)
                .retrieve()
                .body(Boolean.class);
    }

    // 5. DELETE 请求:删除资源
    public void deletePost(Long id) {
        restClient.delete() // 指定 DELETE 方法
                .uri("/posts/{id}", id)
                .retrieve(); // DELETE 请求通常无响应体
    }
}

::: tip 在.retrieve()之前的是请求阶段,在此之后是响应阶段。
因此在此之前的.body()是请求体,在此之后的.body()是响应体。
:::

2.3 进阶用法

2.3.1 设置超时时间

@Bean
public RestClient restClient() {
    // 创建请求工厂,设置超时
    ClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory() {{
        setConnectTimeout(3000); // 连接超时 3 秒
        setReadTimeout(5000);    // 读取超时 5 秒
    }};

    return RestClient.builder()
            .baseUrl(baseUrl)
            .requestFactory(factory) // 设置请求工厂
            .build();
}

2.3.2 添加请求拦截器

@Bean
public RestClient restClient() {
    return RestClient.builder()
            .baseUrl(baseUrl)
            // 添加拦截器
            .requestInterceptor(request -> {
                request.getHeaders().add("Authorization", "Bearer your-token-here");
            })
            .build();
}

2.3.3 自定义响应处理

public String getPostWithErrorHandling(Long id) {
    return restClient.get()
            .uri("/posts/{id}", id)
            .retrieve()
            // 自定义状态码处理
            .onStatus(status -> status.is4xxClientError(), (request, response) -> {
                throw new RuntimeException("客户端错误:" + response.getStatusCode() + ",路径:" + request.getURI());
            })
            .onStatus(status -> status.is5xxServerError(), (request, response) -> {
                throw new RuntimeException("服务端错误:" + response.getStatusCode());
            })
            .body(String.class);
}