当前位置: 首页 > 知识库问答 >
问题:

我们如何使用@ExceptionHandler与Springweb通量?

危彬彬
2023-03-14

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

我曾尝试在web flux controller中使用此注释,但它仍然对我有效,但经过一些调查后,我在这里发现了这一点

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

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

更新:从Spring开始。io看起来它得到了支持,但仍然缺乏普遍的理解

谢谢

共有3个答案

经景辉
2023-03-14

这并不是对原始问题的确切答案,但是将异常映射到http响应状态的一种快速方法是抛出org。springframework。网状物服务器ResponseStatusException/或创建自己的子类。。。

对http响应状态的完全控制spring将添加一个响应主体,该主体带有添加原因的选项。

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

狄法
2023-03-14

现在可以在Spring WebFlux中使用@ExceptionHandler,以及@RestControlller建议,甚至@Controlller建议

例:

>

  • 添加webflux依赖项

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    

    创建类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();
        }
    }
    

    创建一个控制器

    @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/

  • 丁经国
    2023-03-14

    您可以使用@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将按照反应流合同中的预期,将这些异常作为错误信号发送(有关更多信息,请参阅“错误处理”文档部分)。

     类似资料:
    • 我正在尝试构建一个REST应用程序,有一天可能会有数百万客户机使用它。记住这一点,我们预计会收到很多请求。我想知道它是否会倾向于使用冬眠或Spring通量。我们的数据库模型是高度相关的,因此我们不得不拒绝mongo和其他非关系数据库。我有几个问题: spring-webflow和hibernate可以一起使用吗? 如果问题1的答案是否定的,Spring通量是否具有像hibernate这样的缓存功能

    • 我正在研究一些对象的Flux,比如

    • 问题内容: 我们如何或可以通过nte与Meteor一起使用节点模块? 还是依赖于包装API的东西? 还是有建议的处方方法? 问题答案: Meteor 1.3(于2016年3月28日发布)为应用程序提供了完整的ES6(ES2015)模块支持以及现成的NPM支持。应用程序和程序包现在可以直接,轻松地在客户端和服务器上加载NPM模块。 如果可以使用1.3,请检查http://guide.meteor.c

    • “我们在git中甚至在Windows中都使用linux命令。我想知道它是如何让这些linux命令在Windows上运行的?”

    • 我是Android新手,我正在尝试使用UI线程,所以我写了一个简单的测试活动。但我想我误解了什么,因为点击按钮,应用程序不再响应

    • 问题内容: 通道将通信(值的交换)与同步相结合,以确保两个计算(goroutines)处于已知状态。 如何使用Google Go中的频道执行互斥功能? 问题答案: 将通道用作互斥对象的示例: 您也可以使用而不是减小内存大小。输入的值是(type 和一个空的content )。有关示例,请参见Ivan black的评论 。