Spring Boot 3.x 中 WebClient 全面详解及示例
1. WebClient 简介
- 定义:Spring 5 引入的响应式 HTTP 客户端,用于替代(已弃用),支持异步非阻塞的 HTTP 请求。
- 核心特性:
- 支持所有 HTTP 方法(GET/POST/PUT/DELETE 等)。
- 灵活配置请求头、请求体、URI 参数。
- 直接返回或获取响应细节。
- 支持链式调用和响应式流处理。
- 依赖:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-webflux</artifactId>
- </dependency>
复制代码
2. 示例代码详解
示例 1:GET 请求(带请求头,获取状态码和响应头)
- // 1. 创建 WebClient 实例
- WebClient webClient = WebClient.builder()
- .baseUrl("http://api.example.com")
- .build();
- // 2. 发送 GET 请求
- Mono<ResponseEntity<User>> responseMono = webClient.get()
- .uri("/users/{id}", 123) // 路径参数
- .header("Authorization", "Bearer token_123") // 添加请求头
- .retrieve() // 开始发送请求
- .toEntity(User.class); // 转换响应体为 User 对象
- // 3. 处理响应
- responseMono.block().ifPresent(response -> {
- int statusCode = response.getStatusCode().value(); // 状态码
- HttpHeaders headers = response.getHeaders(); // 响应头
- User user = response.getBody(); // 响应体
- });
复制代码
示例 2:POST 请求(传递 JSON 请求体)
- // 1. 创建请求体对象
- User newUser = new User("John", 25);
- // 2. 发送 POST 请求
- Mono<ResponseEntity<String>> responseMono = webClient.post()
- .uri("/users")
- .contentType(MediaType.APPLICATION_JSON) // 设置 Content-Type
- .bodyValue(newUser) // 请求体(自动序列化为 JSON)
- .retrieve()
- .toEntity(String.class); // 返回响应体(如成功返回 "Created")
- // 3. 处理响应
- String locationHeader = responseMono.block().getHeaders().getFirst("Location"); // 获取 Location 头
复制代码
示例 3:PUT/PATCH 请求(更新资源)
- // 1. 更新对象
- User updatedUser = new User("John Doe", 26);
- // 2. 发送 PUT 请求
- Mono<Void> responseMono = webClient.put()
- .uri("/users/123")
- .contentType(MediaType.APPLICATION_JSON)
- .bodyValue(updatedUser)
- .retrieve()
- .toBodilessEntity(); // 无响应体时使用
- // 3. 检查状态码
- responseMono.block(); // 若无异常,则成功
复制代码
示例 4:DELETE 请求
- Mono<Void> responseMono = webClient.delete()
- .uri("/users/123")
- .retrieve()
- .toBodilessEntity();
- // 检查状态码(如 204 No Content)
- responseMono.block();
复制代码
示例 5:自定义响应类型(如 Map)
- Mono<ResponseEntity<Map<String, Object>>> responseMono = webClient.get()
- .uri("/data")
- .retrieve()
- .toEntity(new ParameterizedTypeReference<Map<String, Object>>() {});
- Map<String, Object> data = responseMono.block().getBody();
复制代码
示例 6:使用响应提取器定制返回
- // 自定义提取器:提取响应体中的某个字段
- Mono<String> customHeaderMono = webClient.get()
- .uri("/headers")
- .retrieve()
- .onStatus(HttpStatus::is4xxClientError,
- clientResponse -> Mono.error(new RuntimeException("Client error")))
- .header("X-Custom-Header") // 直接提取指定头
- .switchIfEmpty(Mono.just("Default"));
- String customHeader = customHeaderMono.block();
复制代码
示例 7:批量操作(查询多个资源)
- // 1. 构建带查询参数的 URI
- Mono<User[]> responseMono = webClient.get()
- .uri(uriBuilder -> uriBuilder
- .path("/users")
- .queryParam("page", 1)
- .queryParam("size", 10)
- .build())
- .retrieve()
- .bodyToMono(User[].class); // 返回数组
- User[] users = responseMono.block();
复制代码
3. 核心方法对比表格
| 方法 | HTTP 方法 | 返回类型 | 关键代码片段 | 适用场景 |
|---|
| GET | | - webClient.get().uri("/users/1").retrieve().bodyToMono(User.class);
复制代码 | 简单 GET 请求,直接返回对象 | | GET | - Mono<ResponseEntity<User>>
复制代码 | - webClient.get().uri("/users/1").retrieve().toEntity(User.class);
复制代码 | 需获取状态码或响应头 | | POST | | - webClient.post().bodyValue(newUser).retrieve().bodyToMono(String.class);
复制代码 | 发送 JSON 请求体,直接返回结果 | - put().retrieve().toBodilessEntity()
复制代码 | PUT | | - webClient.put().uri("/users/1").retrieve().toBodilessEntity();
复制代码 | 更新资源,无响应体 | | DELETE | | - webClient.delete().uri("/users/1").retrieve().toBodilessEntity();
复制代码 | 删除资源 |
4. 关键配置与注意事项
设置超时:
- WebClient webClient = WebClient.builder()
- .timeout(Duration.ofSeconds(5))
- .build();
复制代码异常处理:
- Mono<User> response = webClient.get()
- .uri("/users/invalid")
- .retrieve()
- .onStatus(HttpStatus::is4xxClientError,
- clientResponse -> Mono.error(new CustomException()))
- .bodyToMono(User.class);
复制代码自定义序列化:
- ObjectMapper objectMapper = new ObjectMapper();
- WebClient webClient = WebClient.builder()
- .codecs(configurer -> configurer.defaultCodecs()
- .jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper)))
- .build();
复制代码
5. 总结对比表格
| 需求 | 实现方法 | 关键代码 | 注意事项 |
|---|
| 发送 JSON 请求体 | 使用或 | - .contentType(MediaType.APPLICATION_JSON).bodyValue(newUser);
复制代码 | 确保序列化配置正确 | | 获取状态码和响应头 | 返回 | - .retrieve().toEntity(User.class)
复制代码 | 处理 2xx/4xx/5xx 状态码 | | 自定义响应类型 | 使用- ParameterizedTypeReference
复制代码 或泛型 | - .bodyToMono(new ParameterizedTypeReference<List<User>>() {})
复制代码 | 处理复杂泛型类型 | | 响应提取器定制 | 使用、或自定义转换逻辑 | - .header("X-Custom-Header").switchIfEmpty(Mono.just("Default"));
复制代码 | 简化复杂响应处理逻辑 |
关键总结
- 核心类:
- :核心客户端,支持链式调用。
- :响应式类型,处理异步响应。
- :封装响应头、状态码和体。
- 最佳实践:
- 使用统一处理响应。
- 通过处理异常状态码。
- 自定义配置序列化器。
- 响应式特性:
- 非阻塞 I/O,适合高并发场景。
- 需用或处理异步结果(生产环境建议用非阻塞方式)。
通过以上示例和配置,开发者可以高效实现 REST API 的全场景调用需求,充分利用 Spring WebFlux 的响应式优势。
到此这篇关于Spring Boot 3.x 中 WebClient 全面详解及示例的文章就介绍到这了,更多相关springboot webclient内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯! 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |