WebClient 功能介绍
WebClient 是 Spring 5+ 中引入的响应式 HTTP 客户端,用于替代已弃用的 RestTemplate
,专为异步非阻塞编程设计,基于 Reactor 框架实现。其核心功能包括:
异步与非阻塞
通过Mono
和Flux
处理请求与响应,避免线程阻塞,适合高并发场景[1][2][3]。全HTTP方法支持
支持GET
、POST
、PUT
、DELETE
等所有 HTTP 方法,并可灵活配置路径参数、查询参数和请求体[1][4]。响应式流处理
直接返回Mono<ResponseEntity>
或Flux
,可链式调用处理状态码、响应头和响应体,支持流式数据(如 SSE)处理[1][4]。灵活配置
支持全局配置(如基础 URL、默认头)、超时设置、自定义序列化器,以及通过拦截器实现日志记录或认证[1][2]。错误处理机制
提供onStatus
方法处理 HTTP 错误状态码,支持熔断、重试等策略[2][3][4]。
使用场景
微服务间通信
在微服务架构中,通过异步调用实现服务间高效通信,避免线程阻塞[3][4]。高并发与实时数据处理
适用于需要并发处理大量请求的场景(如网关、API 网关),或实时数据流(如股票行情、物联网传感器数据)[3][4]。文件上传/下载
支持多部分表单数据(multipart/form-data
)的异步文件上传,以及大文件的流式下载[3][4]。安全认证集成
内置 OAuth2 支持,可与 Spring Security 结合实现 token 管理[3][4]。超时与重试控制
通过timeout
和retry
方法应对网络不稳定或服务降级场景[3][4]。
完整使用示例演示
1. 创建 WebClient 实例
// 基础配置(无默认头)
WebClient webClient = WebClient.builder()
.baseUrl("http://api.example.com") // 全局基础URL
.build();
// 高级配置(超时、全局头、JSON序列化)
WebClient webClient = WebClient.builder()
.baseUrl("https://api.oauth-provider.com")
.defaultHeader("Authorization", "Bearer your-token") // 全局请求头
.codecs(configurer -> configurer.defaultCodecs()
.jackson2JsonEncoder()) // 自定义JSON序列化
.build();
2. GET 请求(带路径参数和请求头)
Mono<ResponseEntity<User>> responseMono = webClient.get()
.uri("/users/{id}", 123) // 路径参数
.header("X-Custom-Header", "value") // 覆盖默认头
.retrieve()
.toEntity(User.class); // 获取完整响应(状态码、头、体)
// 处理响应
responseMono.block().ifPresent(response -> {
int statusCode = response.getStatusCode().value();
HttpHeaders headers = response.getHeaders();
User user = response.getBody();
});
3. POST 请求(传递 JSON 请求体)
// 同步方式(block)
String response = webClient.post()
.uri("/users")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(new User("John", 25)) // 自动序列化为JSON
.retrieve()
.bodyToMono(String.class)
.block();
// 异步方式(subscribe)
Mono<String> responseMono = webClient.post()
.uri("/users")
.bodyValue(new User("Jane", 30))
.retrieve()
.bodyToMono(String.class);
responseMono.subscribe(result -> System.out.println("Created: " + result));
4. 批量并发请求(处理多个资源)
List<String> productIds = Arrays.asList("1001", "1002", "1003");
List<Mono<Product>> monos = productIds.stream()
.map(id -> webClient.get()
.uri("/products/{id}", id)
.retrieve()
.bodyToMono(Product.class))
.collect(Collectors.toList());
// 合并并发请求
List<Product> products = Flux.merge(monos)
.collectList()
.block(); // 阻塞等待所有请求完成
5. 异常处理与重试机制
Mono<String> responseMono = webClient.get()
.uri("/unstable-endpoint")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(3)) // 设置超时时间
.retry(3) // 重试3次
.onErrorReturn("Fallback response"); // 失败默认值
String result = responseMono.block(); // 若成功返回响应,否则返回"Fallback response"
6. 文件上传(Multipart 表单)
Mono<String> uploadResponse = webClient.post()
.uri("/upload")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData("file", new FileSystemResource("path/to/file.txt")))
.retrieve()
.bodyToMono(String.class);
uploadResponse.block(); // 阻塞等待上传完成
总结
- 核心优势:非阻塞 I/O、响应式流处理、灵活配置,适合高并发和微服务场景[1][3][4]。
- 最佳实践:优先使用
retrieve()
统一处理响应,通过onStatus
处理异常,避免block()
生产环境[2][3]。 - 依赖:需引入
spring-boot-starter-webflux
和响应式库(如 Reactor)。