我们如何利用具有弹簧卷筒料通量的@ExceptionHandler?

在spring Web中,我们可以使用注释@ExceptionHandler来处理控制器的服务器和客户端错误。

我试图将此注释与Web-flux控制器一起使用,它仍然对我有用,但经过一些调查,我在这里发现了

Spring Web Reactive的情况更为复杂。由于反应流由与执行 controllers 方法的线程不同的线程进行评估,因此异常不会自动传播到控制器线程。这意味着 @ExceptionHandler 方法仅适用于直接处理请求的线程中引发的异常。如果我们要使用@ExceptionHandler功能,则必须将流中引发的异常传播回线程。这似乎有点令人失望,但在撰写本文时,Spring 5仍未发布,因此错误处理可能仍然会变得更好。

所以我的问题是如何将异常传播回线程。有没有关于使用@ExceptionHandler和弹簧卷筒纸通量的好例子或文章?

更新:从 spring.io 看起来它得到了支持,但仍然缺乏一般的理解

谢谢


答案 1

您可以使用带注释的方法来处理在执行 WebFlux 处理程序(例如,控制器方法)过程中发生的错误。使用MVC,您确实还可以处理映射阶段发生的错误,但WebFlux并非如此。@ExceptionHandler

回到您的异常传播问题,您分享的文章不准确。

在反应式应用程序中,请求处理确实可以随时从一个线程跳到另一个线程,因此您不能再依赖“每个请求一个线程”模型(想想:)。ThreadLocal

实际上,您不必考虑异常传播或如何管理线程。例如,以下示例应等效:

@GetMapping("/test")
public Mono<User> showUser() {
  throw new IllegalStateException("error message!");
}


@GetMapping("/test")
public Mono<User> showUser() {
  return Mono.error(new IllegalStateException("error message!"));
}

Reactor 将按照 Reactive Streams 合约中的预期将这些异常作为错误信号发送(有关此内容的更多信息,请参阅“错误处理”文档部分)。


答案 2

现在可以使用以及甚至Spring WebFlux。@ExceptionHandler@RestControllerAdvice@ControllerAdvice

例:

  1. 添加 webflux 依赖项

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    
  2. 创建类异常处理程序

    @RestControllerAdvice
    public class ExceptionHandlers {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandlers.class);
    
        @ExceptionHandler(Exception.class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public String serverExceptionHandler(Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            return ex.getMessage();
        }
    }
    
  3. 创建控制器

    @GetMapping(value = "/error", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Mono<String> exceptionReturn() {
        return Mono.error(new RuntimeException("test error"));
    }
    

此处提取的示例:

https://ddcode.net/2019/06/21/spring-5-webflux-exception-handling/


推荐