【WebFlux】第四篇 —— 响应式异常处理与测试

发布时间:2026/9/15 13:35:35
【WebFlux】第四篇 —— 响应式异常处理与测试 告别 try-catch响应式异常处理机制在传统的同步编程中我们习惯用 try-catch 来捕获异常。但在响应式编程中由于代码是声明式的、异步执行的当异常在 map 或 flatMap 内部抛出时它不会中断当前线程而是作为一个“错误信号onError”沿着数据流向下游传播。如果这个信号没有被处理最终会导致整个订阅被终止。Reactor 提供了一套强大的操作符来优雅地处理这些错误onErrorReturn优雅降级当发生异常时直接返回一个默认的兜底值保证流不会中断。Flux.just(1,2,0,4).map(i-10/i)// 遇到 0 时会抛出 ArithmeticException.onErrorReturn(-1)// 捕获异常返回默认值 -1.subscribe(System.out::println);// 输出: 10, 5, -1onErrorResume切换备用流当发生异常时根据异常类型切换到另一个备用的 Publisher数据流。这在处理外部服务调用失败时非常有用。fetchFromPrimaryService().onErrorResume(TimeoutException.class,e-fetchFromBackupService())// 主服务超时自动切换备用服务.subscribe(System.out::println);onErrorMap异常转换将底层的异常如数据库报错转换为业务层更容易理解的自定义异常。userRepository.findById(id).onErrorMap(DataAccessException.class,e-newBusinessException(用户数据获取失败)).subscribe();全局异常拦截ControllerAdvice 的响应式改造除了流级别的处理Spring WebFlux 依然支持我们熟悉的 ControllerAdvice 进行全局异常拦截。需要注意的是在 WebFlux 中处理方法的返回值应该是响应式的 Mono。ControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(BusinessException.class)publicMonoResponseEntityErrorResponsehandleBusinessException(BusinessExceptionex){ErrorResponseerrornewErrorResponse(HttpStatus.BAD_REQUEST.value(),ex.getMessage());returnMono.just(ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error));}}响应式自动化测试利器WebTestClient在 Spring WebFlux 中传统的 MockMvc 无法处理异步流因此官方提供了 WebTestClient。它基于 WebClient 构建专门用于对 WebFlux 端点进行非阻塞的断言测试。实战示例使用 WebFluxTest 进行控制器测试WebFluxTest(UserController.class)// 仅加载 WebFlux 相关的上下文启动极快classUserControllerTest{AutowiredprivateWebTestClientwebTestClient;MockBeanprivateUserServiceuserService;// 模拟 Service 层依赖TestvoidshouldReturnUserWhenExists(){// 1. 定义 Mock 行为Mockito.when(userService.findById(1)).thenReturn(Mono.just(newUser(1,Alice)));// 2. 发起请求并断言webTestClient.get().uri(/api/users/1).exchange()// 执行请求.expectStatus().isOk()// 断言 HTTP 状态码为 200.expectBody()// 断言响应体内容.jsonPath($.name).isEqualTo(Alice);}}响应式流的单元测试StepVerifier如果要测试 Service 层返回的 Flux 或 MonoWebTestClient 就不适用了。此时我们需要引入 reactor-test 依赖并使用 StepVerifier。它是验证异步序列的绝对利器。实战示例验证 Flux 流的行为TestvoidtestUserStream(){FluxStringuserStreamuserService.getActiveUsers();StepVerifier.create(userStream).expectNext(Alice)// 期望第一个元素是 Alice.expectNextMatches(name-name.startsWith(B))// 期望第二个元素以 B 开头.expectNextCount(3)// 期望接下来还有 3 个元素.expectComplete()// 期望流正常结束.verify(Duration.ofSeconds(5));// 设置超时时间防止流卡死}本篇小结响应式编程中的异常处理分为“流级别的操作符降级”和“全局级别的统一拦截”。而在测试方面WebTestClient 和 StepVerifier 是验证响应式逻辑正确性的左膀右臂。下一步预告至此我们已经掌握了 Reactor 的核心语法。下一篇笔记我们将正式回到 Spring WebFlux 框架对比“基于注解的 Controller”与“函数式端点Router Functions”两种编程模型并学习如何使用 WebClient 发起非阻塞的外部 HTTP 调用。准备好进入真正的 Web 开发了吗

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询