Spring Boot 3.x 中 WebClient 全面详解及示例

06-01 1824阅读

Spring Boot 3.x 中 WebClient 全面详解及示例


1. WebClient 简介
  • 定义:Spring 5 引入的响应式 HTTP 客户端,用于替代 RestTemplate(已弃用),支持异步非阻塞的 HTTP 请求。
  • 核心特性:
    • 支持所有 HTTP 方法(GET/POST/PUT/DELETE 等)。
    • 灵活配置请求头、请求体、URI 参数。
    • 直接返回 Mono 或 Flux 获取响应细节。
    • 支持链式调用和响应式流处理。
    • 依赖:
          org.springframework.boot
          spring-boot-starter-webflux
      
      

      2. 示例代码详解

      示例 1:GET 请求(带请求头,获取状态码和响应头)
      // 1. 创建 WebClient 实例
      WebClient webClient = WebClient.builder()
          .baseUrl("http://api.example.com")
          .build();
      // 2. 发送 GET 请求
      Mono 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 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 responseMono = webClient.put()
          .uri("/users/123")
          .contentType(MediaType.APPLICATION_JSON)
          .bodyValue(updatedUser)
          .retrieve()
          .toBodilessEntity(); // 无响应体时使用
      // 3. 检查状态码
      responseMono.block(); // 若无异常,则成功
      

      示例 4:DELETE 请求
      Mono responseMono = webClient.delete()
          .uri("/users/123")
          .retrieve()
          .toBodilessEntity();
      // 检查状态码(如 204 No Content)
      responseMono.block();
      

      示例 5:自定义响应类型(如 Map)
      Mono responseMono = webClient.get()
          .uri("/data")
          .retrieve()
          .toEntity(new ParameterizedTypeReference() {});
      Map data = responseMono.block().getBody();
      

      示例 6:使用响应提取器定制返回
      // 自定义提取器:提取响应体中的某个字段
      Mono 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 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()GETMonowebClient.get().uri("/users/1").retrieve().bodyToMono(User.class);简单 GET 请求,直接返回对象
      retrieve().toEntity()GETMonowebClient.get().uri("/users/1").retrieve().toEntity(User.class);需获取状态码或响应头
      post().bodyValue()POSTMonowebClient.post().bodyValue(newUser).retrieve().bodyToMono(String.class);发送 JSON 请求体,直接返回结果
      put().retrieve().toBodilessEntity()PUTMonowebClient.put().uri("/users/1").retrieve().toBodilessEntity();更新资源,无响应体
      delete()DELETEMonowebClient.delete().uri("/users/1").retrieve().toBodilessEntity();删除资源

      4. 关键配置与注意事项
      • 设置超时:

        WebClient webClient = WebClient.builder()
            .timeout(Duration.ofSeconds(5))
            .build();
        
      • 异常处理:

        Mono 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 请求体使用 bodyValue() 或 body(BodyInserter).contentType(MediaType.APPLICATION_JSON).bodyValue(newUser);确保序列化配置正确
        获取状态码和响应头返回 ResponseEntity.retrieve().toEntity(User.class)处理 2xx/4xx/5xx 状态码
        自定义响应类型使用 ParameterizedTypeReference 或泛型.bodyToMono(new ParameterizedTypeReference() {})处理复杂泛型类型
        响应提取器定制使用 .header()、.bodyToMono() 或自定义转换逻辑.header("X-Custom-Header").switchIfEmpty(Mono.just("Default"));简化复杂响应处理逻辑

        关键总结

        1. 核心类:
          • WebClient:核心客户端,支持链式调用。
          • Mono/Flux:响应式类型,处理异步响应。
          • ResponseEntity:封装响应头、状态码和体。
          • 最佳实践:
            • 使用 retrieve() 统一处理响应。
            • 通过 .onStatus() 处理异常状态码。
            • 自定义 Codecs 配置序列化器。
            • 响应式特性:
              • 非阻塞 I/O,适合高并发场景。
              • 需用 block() 或 subscribe() 处理异步结果(生产环境建议用非阻塞方式)。

        通过以上示例和配置,开发者可以高效实现 REST API 的全场景调用需求,充分利用 Spring WebFlux 的响应式优势。

        Spring Boot 3.x 中 WebClient 全面详解及示例
        (图片来源网络,侵删)
        Spring Boot 3.x 中 WebClient 全面详解及示例
        (图片来源网络,侵删)
        Spring Boot 3.x 中 WebClient 全面详解及示例
        (图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码