在 Java Web 系统开发中,不管是 Controller 层、Service 层还是 Dao 层,都有可能抛出异常。如果在每个方法中加上各种 try catch 的异常处理代码,那样会使代码非常繁琐。在Spring MVC 中,我们可以将所有类型的异常处理从各个单独的方法中解耦出来,进行异常信息的统一处理和维护。
在 Spring MVC 中全局异常捕获处理的解决方案通常有两种方式:
1.使用 @ControllerAdvice + @ExceptionHandler 注解进行全局的 Controller 层异常处理。
2.实现 org.springframework.webb.servlet.HandlerExceptionResolver 接口中的 resolveException 方法。
使用 @ControllerAdvice + @ExceptionHandler 注解 1.定义统一异常处理类 @ControllerAdvice public class GlobalExceptionHandler { private Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ExceptionHandler(value = Exception.class) public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) { log.error("ExceptionHandler ===>" + e.getMessage()); e.printStackTrace(); // 这里可根据不同异常引起的类做不同处理方式 String exceptionName = ClassUtils.getShortName(e.getClass()); log.error("ExceptionHandler ===>" + exceptionName); ModelAndView mav = new ModelAndView(); mav.addObject("stackTrace", e.getStackTrace()); mav.addObject("errorMessage", e.getMessage()); mav.addObject("url", req.getRequestURL()); mav.setViewName("forward:/error/500"); return mav; } }其中 @ExceptionHandler(value = Exception.class) 中的捕获异常 value 可以自定义,如下:
类型 描述NullPointerException 当应用程序试图访问空对象时,则抛出该异常
SQLException 提供关于数据库访问错误或其他错误信息的异常
IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出
NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常
FileNotFoundException 当试图打开指定路径名表示的文件失败时,抛出此异常
IOException 当发生某种I/O异常时,抛出此异常。此类是失败或中断的I/O操作生成的异常的通用类
ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常
ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数
ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例
NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异常
NoSuchMethodException 无法找到某一特定方法时,抛出该异常
SecurityException 由安全管理器抛出的异常,指示存在安全侵犯
UnsupportedOperationException 当不支持请求的操作时,抛出该异常
RuntimeException 是那些可能在Java虚拟机正常运行期间抛出的异常的超类
当捕获到响应的异常类型时,会进入 defaultErrorHandler() 方法中的逻辑:把异常信息放入 model,跳转至 /error/500 请求URL。
2.异常信息展现视图控制器配置
@Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { /** * 视图控制器配置 */ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("http://www.likecs.com/").setViewName("/index");//设置默认跳转视图为 /index registry.addViewController("/error/500").setViewName("/error/500"); registry.setOrder(Ordered.HIGHEST_PRECEDENCE); super.addViewControllers(registry); } }视图模板
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>Exception</h1> <h3 th:text="${url}"></h3> <h3 th:text="${errorMessage}"></h3> <p th:each="line : ${stackTrace}" th:text="${line}"> </p> </body> </html> 3.测试异常类 @Controller public class TestController { @GetMapping("/index") public String hello() { int x = 1 / 0; return "hello"; } } 4.运行测试浏览器访问::8080/index