在spring web中,我们可以使用注释@ExceptionHandler来处理控制器的服务器和客户端错误。
我尝试将此注释与web-flux控制器一起使用,它仍然适用于我,但经过一些调查后我发现here
Spring Web Reactive的情况更复杂。因为 反应流由不同的线程评估 执行控制器方法,异常不会 自动传播到控制器线程。这意味着 @ExceptionHandler方法仅适用于抛出的异常 在直接处理请求的线程中。抛出异常 如果我们愿意,必须将流传播回线程 使用@ExceptionHandler功能。这似乎有点让人失望 但在撰写本文时,今年春天仍未发布 错误处理可能会变得更好。
所以我的问题是如何将异常传播回线程。是否有关于使用@ExceptionHandler和Spring web flux的好例子或文章?
更新: 从spring.io来看,它似乎得到了支持,但仍然缺乏一般性的理解
谢谢,
答案 0 :(得分:6)
您可以使用@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!));
}
Reactor会将这些异常作为Reactive Streams合同中预期的错误信号发送(有关详细信息,请参阅the "error handling" documentation section)。
答案 1 :(得分:2)
不是原始问题的确切答案,但是将异常映射到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\""
}
答案 2 :(得分:2)
现在可以在 Spring WebFlux 中使用 @ExceptionHandler
和 @RestControllerAdvice
甚至 @ControllerAdvice
。
示例:
添加 webflux 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
创建您的类 ExceptionHandler
@RestControllerAdvice 公共类 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();
}
}
创建控制器
@GetMapping(value = "/error",produces = MediaType.APPLICATION_JSON_UTF8_VALUE) 公共单声道异常返回(){ return Mono.error(new RuntimeException("test error")); }
此处提取的示例:
https://ddcode.net/2019/06/21/spring-5-webflux-exception-handling/