springMVC–异常处理
基本介绍
1.Spring MVC 通过HandlerExceptionResolver 处理程序的异常,包括Handler 映射、数据绑定以及目标方法执行时发生的异常。
2.主要处理Handler 中用@ExceptionHandler 注解定义的方法。
3.ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话, 会找@ControllerAdvice 类的@ExceptionHandler 注解方法, 这样就相当于一个全局异常处理器。
局部异常
应用实例
演示局部异常处理机制
如果不处理异常, 对用户非常的不友好。
代码实现
创建springmvc\src\com\web\exception\MyExceptionHandler.java
@Controller public class MyExceptionHandler { /** * 1. localException 方法处理局部异常 * 2. 这里处理ArithmeticException.class,NullPointerException.class类型的异常 * 3. Exception ex: 生成的异常对象,会传递给ex, 通过ex可以得到相关的异常信息,这里程序员可以加入自己的业务逻辑 */ @ExceptionHandler({ArithmeticException.class,NullPointerException.class}) public String localException(Exception ex, HttpServletRequest request){ System.out.println("局部异常信息是-" + ex.getMessage()); //如何将异常的信息带到下一个页面. request.setAttribute("reason", ex.getMessage()); return "exception_mes"; } /** * 1. 编写方法,模拟异常, 算术异常 * 2. 如果我们不做异常处理,是由tomcat默认页面显示 */ @RequestMapping(value = "/testException01") public String test01(Integer num) { int i = 9 / num; return "success"; } }
创建springmvc\web\exception.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>异常信息</title> </head> <body> <h1>测试异常</h1> <a href="testException01?num=0">点击测试异常</a><br><br> </body> </html>
创建显示异常信息页面/WEB-INF/pages/exception_mes.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>异常信息提示</title> </head> <body> <h1>朋友, 程序发生了异常...</h1> 异常信息- ${requestScope.reason} </body> </html>
测试(页面方式)
浏览器输入http://localhost:8080/springmvc/exception.jsp
感兴趣的可以debug一下源码。
全局异常
应用实例
应用实例需求
演示全局异常处理机制, ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话,会找@ControllerAdvice 类的@ExceptionHandler 注解方法,这样就相当于一个全局异常处理器。
代码实现
创建springmvc\src\com\web\exception\MyGlobalException.java
// 如果类上标注了@ControllerAdvice,就是一个全局异常处理类 @ControllerAdvice public class MyGlobalException { /** * 1. 全局异常就不管是哪个Handler抛出的异常,都可以捕获 , @ExceptionHandler({异常类型}) * 2. 这里处理的全局异常是NumberFormatException.class,ClassCastException.class * 3. Exception ex 接收抛出的异常对象 */ @ExceptionHandler({NumberFormatException.class, ClassCastException.class}) public String globalException(Exception ex, HttpServletRequest request) { System.out.println("全局异常处理-" + ex.getMessage()); //如何将异常的信息带到下一个页面. request.setAttribute("reason", ex.getMessage()); return "exception_mes"; } }
修改MyExceptionHandler.java , 增加方法
@RequestMapping(value = "/testGlobalException") public String global(){ //1. 这里我们模拟了一个异常 NumberFormatException //2. 该异常没有在局部异常处理,按照异常处理机制,就会交给全局异常处理类处理 int num = Integer.parseInt("hello"); return "success"; }
修改exception.jsp
<a href="testException01?num=0">点击测试异常</a><br><br> <a href="testGlobalException">点击测试全局异常</a><br><br>
完成测试(页面方式)
浏览器输入http://localhost:8080/springmvc/exception.jsp
自定义异常
应用实例
应用实例需求
通过@ResponseStatus 注解, 可以自定义异常的说明。
应用实例-代码实现
创建springmvc\src\com\web\exception\AgeException.java
@ResponseStatus(reason="年龄需要在1-120 之间",value= HttpStatus.BAD_REQUEST) public class AgeException extends RuntimeException{ }
修改MyExceptionHandler.java, 增加方法
//抛出自定义异常 @RequestMapping(value="/testException02") public String test02(){ throw new AgeException(); }
修改exception.jsp, 增加超链接
<a href="testGlobalException">点击测试全局异常</a><br><br> <a href="testException02">点击测试自定义异常</a><br/><br/>
完成测试
浏览器输入http://localhost:8080/springmvc/exception.jsp
全局异常处理—SimpleMappingExceptionResolver
基本说明
- 如果希望对所有异常进行统一处理,可以使用SimpleMappingExceptionResolver。
- 它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。
- 需要在ioc 容器中配置。
应用实例
需求
对数组越界异常进行统一处理,使用SimpleMappingExceptionResolver.
代码实现
- 修改MyExceptionHandler.java , 增加方法test03
//统一的异常 @RequestMapping(value="/testException03") public String test03(){ int[] arr = new int[]{3,9,10,190}; System.out.println(arr[90]); return "success"; }
- 配置springDispatcherServlet-servlet.xml
<!--配置统一处理异常Bean--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop> </props> </property> </bean> <!-- 加入两个常规配置--> <!-- 能支持SpringMVC 高级功能,比如JSR303 校验,映射动态请求--> <mvc:annotation-driven></mvc:annotation-driven> <!-- 将SpringMVC 不能处理的请求交给Tomcat, 比如请求css,js 等--> <mvc:default-servlet-handler/>
创建/WEB-INF/pages/arrEx.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>数组越界了</title> </head> <body> <h1>数组越界了~</h1> </body> </html>
- 修改exception.jsp
<a href="testException03"> 测试统一的异常[SimpleMappingExceptionResolver]</a>
完成测试(页面测试)
浏览器输入http://localhost:8080/springmvc/exception.jsp
对未知异常进行统一处理
需求
对未知异常进行统一处理,使用SimpleMappingExceptionResolver。
代码实现
- 修改MyExceptionHandler.java , 增加方法test04
//如果发生了没有归类的异常, 可以给出统一提示页面 @RequestMapping(value="/testException04") public String test04(){ String str = "hello"; char c = str.charAt(10); return "success"; }
- 配置springDispatcherServlet-servlet.xml
<!--配置统一处理异常Bean--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop> <prop key="java.lang.Exception">allEx</prop> </props> </property> </bean>
- 创建/WEB-INF/pages/otherEx.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>未知异常信息</title> </head> <body> <h1>朋友,系统发生了未知异常~</h1> </body> </html>
- 修改exception.jsp , 增加超链接
<a href="testException03"> 测试统一的异常[SimpleMappingExceptionResolver]</a> <br/><br/><a href="testException04"> 统一未归类异常</a>
完成测试(页面测试)
浏览器输入http://localhost:8080/springmvc/exception.jsp
小结
异常处理的优先级
局部异常> 全局异常> SimpleMappingExceptionResolver > tomcat 默认机制。