【问题标题】:How to handle exception thrown from ExceptionHandler in controller with ExceptionHandler in ControllerAdvice?如何使用ControllerAdvice中的ExceptionHandler处理控制器中的ExceptionHandler引发的异常?
【发布时间】:2017-03-21 23:45:02
【问题描述】:

我有自定义 Exceptions 扩展 Exception (MyException1, MyException2, MyException3)

@Controller
public class MyController {
    /*
       Method throwing MyException1
       Method throwing MyException2
       Method throwing MyException3
    */

    @ExceptionHandler(MyException1.class)
    public void handleMyException1(Exception ex){
        //Do something
        throw ex;
    }
    @ExceptionHandler(MyException2.class)
    public void handleMyException2(Exception ex){
        System.out.println("Exception Logged inside Controller")
    }
}

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public void handleAllException(Exception ex){
        System.out.println("Exception logged Outside Controller");
    }
}
我的意图:从控制器建议中记录 MyException1 在控制器本身的处理程序中记录 MyException2 从控制器建议中记录 MyException3 MyException2 和 MyException3 正在按预期工作,但 MyException1 失败并显示
“无法调用 @ExceptionHandler 方法 .....handleMyException1”

【问题讨论】:

  • 如果你想从 MyGlobalExceptionHandler 处理 MyException1 那么你为什么要在 MyController 中处理它呢?为什么不在handleAllException中放一个“if (ex instanceof MyException1) ...”
  • 对于“做某事”它特定于从 MyController 创建的 MyException1。然后它类似于从任何其他控制器创建的其他 MyException1 并且可以在 Global Advice 中安全处理。同样根据我的理解,如果控制器内部没有提供异常,spring应该查看ControllerAdvice。哪个没有发生,所以想知道我在这里做错了什么?我认为这样代码会更干净,因为控制器特定的逻辑将驻留在控制器的处理程序本身中
  • 我不确定你能做到这一点。 Spring 期望异常处理程序使用异常。您总是可以在 MyController 中捕获 MyException1 并将其包装在一个新类中,例如。 MyControllerMyException1,然后在您的异常处理程序中处理它。
  • 创建ControllerAdvice类的实例并手动调用handleAllException不是更好吗?这可能是一个解决方案,但通过查看全局建议 (ControllerAdvice) 来寻找 spring 为我处理它的东西
  • 你当然可以这样做。另一种方法是让 MyGlobalExceptionHandler 处理它;检查堆栈跟踪以查看它是否来自 MyController。

标签: java spring spring-mvc exception-handling spring-aop


【解决方案1】:

您可以选择以下选项之一进行异常处理:

Option(1) :从 Controller 中移除 @ExceptionHandler(MyException1.class) 方法,以便由 MyGlobalExceptionHandler 自动处理。

Option(2) :创建MyException4(这是MyException1 的包装器,带有附加信息)并从Controller 中抛出,如下所示:

@Controller
public class MyController {
    /*
       Method throwing MyException1
       Method throwing MyException2
       Method throwing MyException3
    */

    @ExceptionHandler(MyException1.class)
    public void handleMyException1(Exception ex){
         //MyException4 exe4 = new MyException4();
        // Add the required details to it
        throw exe4;
    }

    @ExceptionHandler(MyException2.class)
    public void handleMyException2(Exception ex){
        System.out.println("Exception Logged inside Controller")
    }
}

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public void handleAllException(Exception ex){
        System.out.println("Exception logged Outside Controller");
    }
}

P.S.:我这里没有添加Option(3),这是手动调用MyGlobalExceptionHandlerhandleAllException(),因为这不是一个好习惯。相反,您应该简单地抛出异常,@ExceptionHandler 会自动处理。

手动调用的另一个问题是,在将来的某个时间点,调试异常会出现问题,因为您的某些流程手动调用MyGlobalExceptionHandler,而某些流程由框架调用。

【讨论】:

    猜你喜欢
    • 2019-11-23
    • 2011-02-21
    • 2011-05-12
    • 2016-05-21
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 2021-03-24
    相关资源
    最近更新 更多