我们怎样才能将@ExceptionHandler与spring web flux结合使用?

Evg*_*gen 5 java spring exceptionhandler spring-webflux

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

我已经尝试使用这个注释与web-flux控制器,它仍然适用于我,但经过一些调查,我发现在这里

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

所以我的问题是如何将异常传播回线程.有没有关于使用@ExceptionHandler和Spring web flux的好例子或文章?

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

谢谢,

Edd*_*nne 15

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

例子:

  1. 添加 webflux 依赖项

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建您的类 ExceptionHandler

    @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();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建控制器

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

此处提取的示例:

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

  • 可以肯定,只有当您的项目中包含 spring MVC spring-boot-starter-web 时,这才有效。 (2认同)

Bri*_*zel 7

您可以使用带@ExceptionHandler注释的方法来处理在执行WebFlux处理程序(例如,您的控制器方法)中发生的错误.使用MVC,您确实可以处理映射阶段发生的错误,但WebFlux不是这种情况.

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

在反应式应用程序中,请求处理确实可以随时从一个线程跳到另一个线程,因此您不能再依赖"每个请求一个线程"模型(想想:) 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!));
}
Run Code Online (Sandbox Code Playgroud)

Reactor会将这些异常作为Reactive Streams合同中预期的错误信号发送(有关详细信息,请参阅"错误处理"文档部分).


Har*_*mut 5

不是原始问题的确切答案,但将异常映射到 http 响应状态的快速方法是抛出org.springframework.web.server.ResponseStatusException/或创建您自己的子类...

完全控制http响应状态+ spring将添加一个响应主体,并可以选择添加reason.

{
    "timestamp": 1529138182607,
    "path": "/api/notes/f7b.491bc-5c86-4fe6-9ad7-111",
    "status": 400,
    "error": "Bad Request",
    "message": "For input string: \"f7b.491bc\""
}
Run Code Online (Sandbox Code Playgroud)