spingmvc 异常处理[ 尚硅谷笔记 ]
模拟异常:[springmvc]
index.jsp
1 <a href="testExceptionHandlerExceptionResolver?i=10">Test ExceptionHandlerExceptionResolver</a>
EmployeeHandler.java
1 @Controller 2 public class EmployeeHandler { 3 4 @RequestMapping("/testExceptionHandlerExceptionResolver") 5 public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i) { 6 System.out.println("result: " + (10/i)); 7 return "success"; 8 } 9 }
success.jsp
1 <body> 2 success 3 </body>
运行:
-----上面直接抛出异常, 页面显得不友好, 希望把异常的信息输出到页面上友好展示
在handler中添加代码:
1 @ExceptionHandler({ArithmeticException.class}) 2 public String handleArithmeticException(Exception ex) { 3 System.out.println("出异常了: " + ex); 4 return "error"; 5 }
error.jsp
1 <body> 2 <h3>Error Page</h3> 3 </body>
运行:
后台打印:
--------------下面是把异常输出到页面上:
1 @Controller 2 public class EmployeeHandler { 3 4 @RequestMapping("/testExceptionHandlerExceptionResolver") 5 public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i) { 6 System.out.println("result: " + (10/i)); 7 return "success"; 8 } 9 10 /** 11 * 1. 在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象 12 * 2. @ExceptionHandler 方法的入参中不能传入 Map. 若希望把异常信息传导页面上, 需要使用 ModelAndView 作为返回值 13 */ 14 @ExceptionHandler({ArithmeticException.class}) 15 public ModelAndView handleArithmeticException(Exception ex) { 16 System.out.println("出异常了: " + ex); 17 ModelAndView mv = new ModelAndView("error"); 18 mv.addObject("exception", ex); 19 return mv; 20 } 21 }
1 <body> 2 <h3>Error Page</h3> 3 ${exception } 4 </body>
运行:
-------以上是在handler中处理异常, 而实际开发中应该在异常处理类中处理异常
新建包com.atguigu.springmvc.exception,包下创建异常处理类: SpringMVCTestExceptionHandler.java
[注意在springmvc.xml中配置注解驱动<mvc:annotation-driven/>, 否则找不到这个异常处理类]
1 @ControllerAdvice 2 public class SpringMVCTestExceptionHandler { 3 4 @ExceptionHandler({ArithmeticException.class}) 5 public ModelAndView handleArithmeticException(Exception ex) { 6 System.out.println("出异常了---------->" + ex); 7 ModelAndView mv = new ModelAndView("error"); 8 mv.addObject("exception", ex); 9 return mv; 10 } 11 12 }
把原先的handler中的处理异常的方法注释掉, 再测试:
后台打印:
@ControllerAdvice:
如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常.
这个类似于struts2中的ExceptionMapping, 不过springmvc是使用方法和注解的形式处理异常, 再次说明springmvc是基于方法和注解开发的, 而struts2是
基于类开发的
这样使用专门的异常处理类来处理异常, 可以在这里写具体的逻辑处理, 显得更加地灵活和清晰.
--------------- 下面是自定义的异常页面显示
情景模拟:
在包com.atguigu.springmvc.exception下创建自定义异常类UserNameNotMatchPasswordException.java[暂时先不需要写东西, 测试用]
1 public class UserNameNotMatchPasswordException extends RuntimeException{ 2 3 private static final long serialVersionUID = 1L; 4 5 }
index.jsp
1 <a href="testResponseStatusExceptionResolver?id=13">Test ResponseStatusExceptionResolver</a>
EmployeeHandler.java
1 @RequestMapping("/testResponseStatusExceptionResolver") 2 public String testResponseStatusExceptionResolver(@RequestParam("id") int id) { 3 if (id == 13) { 4 System.out.println("testResponseStatusExceptionResolver....."); 5 throw new UserNameNotMatchPasswordException(); 6 } 7 return "success"; 8 }
运行结果:
希望如果出异常的时候在红色框中显示自定义的异常信息, 比如: 用户名和密码不匹配等信息
修改UserNameNotMatchPasswordException.java
1 @ResponseStatus(value=HttpStatus.FORBIDDEN, reason="用戶名和密碼不匹配") 2 public class UserNameNotMatchPasswordException extends RuntimeException{ 3 4 private static final long serialVersionUID = 1L; 5 6 }
再次运行: 显示自定义的异常信息
以上是直接在类上标识注解, 在地址栏输入:http://localhost:8080/springmvc_emp_exception/testResponseStatusExceptionResolver?id=13
才会出现以上的自定义的异常信息, 这时候如果把id改成非异常, 比如:
http://localhost:8080/springmvc_emp_exception/testResponseStatusExceptionResolver?id=10, 就不会出异常:
但是如果直接在方法上配置自定义的异常注解, 那么不管这个方法是否发生异常, 都会来到自定义的异常页面, 比如:
EmployeeHandler.java:
1 @RequestMapping("/testResponseStatusExceptionResolver") 2 @ResponseStatus(reason="测试", value=HttpStatus.NOT_FOUND) // 这里随便定义一个异常, 只是测试用 3 public String testResponseStatusExceptionResolver(@RequestParam("id") int id) { 4 // 这时候不管id是否等于13, 都会去到异常页面 5 if (id == 13) { 6 System.out.println("testResponseStatusExceptionResolver....."); 7 throw new UserNameNotMatchPasswordException(); 8 } 9 return "success"; 10 }
测试:http://localhost:8080/springmvc_emp_exception/testResponseStatusExceptionResolver?id=10
测试:http://localhost:8080/springmvc_emp_exception/testResponseStatusExceptionResolver?id=13
---------下面是异常异常跳转到页面
情景模拟: 数组下标越界异常
index.jsp
1 <a href="testSimpleMappingExceptionResolver?i=5">Test SimpleMappingExceptionResolver</a>
EmployeeHandler.java:
1 @RequestMapping("/testSimpleMappingExceptionResolver") 2 public String testSimpleMappingExceptionResolver(@RequestParam("i") int i) { 3 String []vals = new String[10]; // 定义一个数组, 测试数据下标越界异常 4 System.out.println(vals[i]); 5 return "success"; 6 }
测试:
-------------- 如果出现异常, 希望跳转到到异常页面, 并显示异常信息
在springmvc.xml中配置
1 <!-- 配置使用SimpleMappingExceptionResolver来映射异常 --> 2 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 3 <property name="exceptionAttribute" value="ex"/> <!-- 在页面上使用${requestScope.ex }获取异常信息 --> 4 <property name="exceptionMappings"> 5 <props> 6 <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop> 7 </props> 8 </property> 9 </bean>
测试:
在错误页面添加图片, 让页面显得更加友好: