diff --git a/spring/Spring core/SpringMVC.md b/spring/Spring core/SpringMVC.md index 9378e72..5c8cd96 100644 --- a/spring/Spring core/SpringMVC.md +++ b/spring/Spring core/SpringMVC.md @@ -577,7 +577,7 @@ public class SimpleController { } } ``` -该异常参数会匹配被抛出的顶层异常(例如,被直接抛出的IOException),也会匹配被包装的内层cause(例如,被包装在IllegalStateException中的IOException)。**该参数会匹配任一层级的cause。** +该异常参数会匹配被抛出的顶层异常(例如,被直接抛出的IOException),也会匹配被包装的内层cause(例如,被包装在IllegalStateException中的IOException)。**该参数会匹配任一层级的cause exception,并不是只有该异常的直接cause exception才会被处理。** > 只要@ExceptionHandler方法的异常参数类型匹配异常抛出stacktrace中任一层次的异常类型,异常都会被捕获并且处理。 ```java @PostMapping("/shiro") @@ -590,5 +590,43 @@ public class SimpleController { return e.getMessage() + ", Jar"; } ``` -> 如果有多个@ExceptionHandler方法匹配抛出的异常链,那么 +> 如果有多个@ExceptionHandler方法匹配抛出的异常链,那么root exception匹配会优先于cause exception匹配。 +> ExceptionDepthComparator会根据各个异常类型相对于抛出异常类型(root exception)的深度来进行排序。 +> ```java +> // 在调用/shiro接口时,IOException离root exception(RuntimeException)更近, +> // 故而会优先调用handleIOException方法 +> @PostMapping("/shiro") +> public String shiro() throws IOException { +> throw new RuntimeException(new IOException(new SQLException("fuck"))); +> } +> +> @ExceptionHandler +> public String handleIOException(IOException e) { +> return e.getMessage() + ", IO"; +> } +> +> @ExceptionHandler +> public String handleSQLException(SQLException e) { +> return e.getMessage() + ",Exception"; +> } +> ``` + +对于@ExceptionHandler,可以指定该方法处理的异常类型来缩小范围,如下方法都只会匹配root exception为指定异常或异常链中包含指定异常的场景: +```java +@ExceptionHandler({FileSystemException.class, RemoteException.class}) +public ResponseEntity handle(IOException ex) { + // ... +} + +// 甚至,可以将参数的异常类型指定为一个非常宽泛的类型,例如Exception +@ExceptionHandler({FileSystemException.class, RemoteException.class}) +public ResponseEntity handle(Exception ex) { + // ... +} +``` +上述两种写法的区别是: +1. 如果参数类型为IOException,那么当cause exception为FileSystemException或RemoteException,且root exception为IOException时,实际的cause exception要通过ex.getCause来获取 +2. 如果参数类型为Exception,那么当cause exception为FileSystemException或RemoteException且root exception不为指定类型异常时,指定类型异常统一都通过ex.getCause来获取 + +