java - Spring @Controller 异常处理程序和全局异常处理程序。如何调用两者

标签 java spring spring-mvc spring-boot

我有一个全局异常处理程序可以在 REST @Controller 之间共享。为此,我使用 @ControllerAdvice 和一些 @ExceptionHandler 方法。这很好用。现在,如果我在特定的 Rest Controller 中添加一个 @ExceptionHandler ,那么该新处理程序将优先于全局异常处理程序,并且全局异常处理程序永远不会被调用。

我实际上需要的是同时调用两者。顺序并不重要。关键是有一些全局的、与 Controller 无关的错误处理代码以及一些特定于 Controller 的错误处理代码,我需要两者都执行。这可能吗?例如我可以以某种方式在特定于 Controller 的处理程序(首先调用)中将异常处理标记为未处理,以便调用下一个处理程序吗?

我知道我可以在 @Controller 中注入(inject) @ControllerAdvice 并自己从特定的处理程序中调用全局处理程序,但我宁愿让 Controller 与全局解耦异常处理程序

最佳答案

我认为你不能用开箱即用的 Spring 来做到这一点。如果您仔细查看此方法 ExceptionHandlerExceptionResolver#doResolveHandlerMethodException ,你可以看到 Spring 首先寻找单个方法来处理发生的异常:

    ...
    ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
    if (exceptionHandlerMethod == null) {
        return null;
    }
    ...

您还可以查看 getExceptionHandlerMethod 的实现方法。首先,它尝试在 Controller 方法中找到适当的处理程序,如果没有找到,则在 Controller 顾问程序中找到。

之后它调用它:

    try {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking @ExceptionHandler method: " + exceptionHandlerMethod);
        }
        exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception, handlerMethod);
    }
    catch (Exception invocationEx) {
        if (logger.isErrorEnabled()) {
            logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
        }
        return null;
    }

您还应该注意,Spring 吞掉了原始异常处理期间可能发生的任何异常,因此您甚至无法从第一个处理程序中抛出新异常或重新抛出原始异常,以便可以在其他地方捕获它(实际上可以,但是这是毫无意义的)。

所以,如果你真的想这样做 - 我想唯一的方法就是写你自己的 ExceptionHandlerExceptionResolver (也许扩展 Springs ExceptionHandlerExceptionResolver )并修改 doResolveHandlerMethodException方法,因此它会查找乘法 exceptionHandlerMethod (一个在 Controller 内,一个在顾问内)并在链中调用它。这可能很棘手:)

另外,您可以查看this Jira 门票。

希望有帮助。

关于java - Spring @Controller 异常处理程序和全局异常处理程序。如何调用两者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46087710/

相关文章:

java - 在Android项目中导入源码java项目

java - 自定义类加载失败,出现 java.lang.IllegalAccessError : Class ref in pre-verified class resolved to unexpected implementation

java - 从自定义 ItemReader 访问时无法强制转换 FlatFileItemReader

java - Spring WS 客户端发送 HTTPS 请求

java - Spring MVC/Hibernate/mySQL "read"始终为空

c# - 加密和解密

java - 将变量声明为类级常量是否比局部变量更能提高性能?

java - Spring + Jackson,要求 double 序列化时尾随 0

java - Spring @Value 字段为空

json - Spring 配置 - mvc :annotation-driven, AnnotationMethodHandlerAdapter 和 JSON