【问题标题】:Spring @Controller exception handler and global exception handler. How to invoke bothSpring @Controller 异常处理程序和全局异常处理程序。如何调用两者
【发布时间】:2017-09-07 04:17:54
【问题描述】:

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

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

我知道我可以在@Controller 中注入@ControllerAdvice 并自己从特定的处理程序中调用全局处理程序,但我宁愿将控制器与全局异常处理程序分离

【问题讨论】:

    标签: java spring spring-mvc spring-boot


    【解决方案1】:

    我认为你不能使用开箱即用的 Spring 来做到这一点。如果你深入了解这个方法ExceptionHandlerExceptionResolver#doResolveHandlerMethodException,你可以看到一开始 Spring 正在寻找 single 方法来处理发生的异常:

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

    你也可以看看getExceptionHandlerMethod方法的实现。首先它试图在你的控制器方法中找到合适的处理程序,如果没有找到 - 然后在控制器顾问中。

    之后它会调用它:

        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(一个在控制器中,一个在顾问中)并在链中调用它。这可能很棘手:)

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

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      • 2012-12-31
      • 2011-05-19
      • 2011-08-31
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多