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

134 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: SpringBoot RestClient简介
date: 2026-01-06
---
# 一、简介
  RestClient 是 Spring Framework 6.1(及对应的 Spring Boot 3.2+)推出的新一代同步 HTTP 客户端,设计目标是替代传统的 RestTemplateSpring 已标记 RestTemplate 为维护模式,不再新增功能),同时结合了 WebClient 的流畅 API 设计,又保持了 RestTemplate 的同步、简单易用的特点。
# 二、使用
## 2.1 创建实例
```java
@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请求
```java
@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 设置超时时间
```java
@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 添加请求拦截器
```java
@Bean
public RestClient restClient() {
return RestClient.builder()
.baseUrl(baseUrl)
// 添加拦截器
.requestInterceptor(request -> {
request.getHeaders().add("Authorization", "Bearer your-token-here");
})
.build();
}
```
### 2.3.3 自定义响应处理
```java
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);
}
```