SpringMVC系列(十三)异常处理
一、简介
• Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。
• SpringMVC 提供的 HandlerExceptionResolver 的实现类
• DispatcherServlet 默认装配的 HandlerExceptionResolver :
– 没有使用 <mvc:annotation-driven/> 配置:
– 使用了 <mvc:annotation-driven/> 配置:
二、ExceptionHandlerExceptionResolver
在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象
@ExceptionHandler 方法的入参中不能传入 Map. 若希望把异常信息传导页面上, 需要使用 ModelAndView 作为返回值
@ExceptionHandler 方法标记的异常有优先级的问题.
@ControllerAdvice: 如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 则将去 @ControllerAdvice 标记的类中查找@ExceptionHandler 标记的方法来处理异常.
1. 编写异常handle
1 @ExceptionHandler({RuntimeException.class}) 2 public ModelAndView handleArithmeticException2(Exception ex){ 3 System.out.println("[出异常了]: " + ex); 4 ModelAndView mv = new ModelAndView("error"); 5 mv.addObject("exception", ex); 6 return mv; 7 } 8 9 ////优先级高于handleArithmeticException2,如果没有找到具体的异常就使用handleArithmeticException2 10 @ExceptionHandler({ArithmeticException.class}) 11 public ModelAndView handleArithmeticException(Exception ex){ 12 System.out.println("出异常了: " + ex); 13 ModelAndView mv = new ModelAndView("error"); 14 mv.addObject("exception", ex); 15 return mv; 16 } 17 18 @RequestMapping("/testExceptionHandlerExceptionResolver") 19 public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i){ 20 System.out.println("result: " + (10 / i)); 21 return "success"; 22 }
2.在jsp页面发送请求
1 <a href="testExceptionHandlerExceptionResolver?i=0">Test ExceptionHandlerExceptionResolver</a>
3. 编写错误回显的页面error.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 11 <h4>Error Page</h4> 12 13 ${requestScope.exception } 14 15 </body> 16 </html>
备注:
如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 则将去 @ControllerAdvice 标记的类中查找@ExceptionHandler 标记的方法来处理异常.
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 }
三、ResponseStatusExceptionResolver
在异常及异常父类中找到 @ResponseStatus 注解,然后使用这个注解的属性进行处理。
1.定义一个 @ResponseStatus 注解修饰的异常类
1 @ResponseStatus(value=HttpStatus.FORBIDDEN, reason="用户名和密码不匹配!") 2 public class UserNameNotMatchPasswordException extends RuntimeException{ 3 4 /** 5 * 6 */ 7 private static final long serialVersionUID = 1L; 8 9 10 }
2.编写handle
使用@ResponseStatus标注的方法即使没有异常也会报异常
1 @ResponseStatus(reason="测试",value=HttpStatus.NOT_FOUND) 2 @RequestMapping("/testResponseStatusExceptionResolver") 3 public String testResponseStatusExceptionResolver(@RequestParam("i") int i){ 4 if(i == 13){ 5 throw new UserNameNotMatchPasswordException(); 6 } 7 System.out.println("testResponseStatusExceptionResolver..."); 8 9 return "success"; 10 }
3.在jsp页面发送请求
1 <a href="testResponseStatusExceptionResolver?i=13">Test ResponseStatusExceptionResolver</a>
使用@ResponseStatus标注的方法即使没有异常也会报异常
四、DefaultHandlerExceptionResolver
对一些特殊的异常进行处理,比如NoSuchRequestHandlingMethodException、HttpRequestMethodNotSupportedException、HttpMediaTypeNotSupportedException、HttpMediaTypeNotAcceptableException等
1.编写handle
1 @RequestMapping(value="/testDefaultHandlerExceptionResolver",method=RequestMethod.POST) 2 public String testDefaultHandlerExceptionResolver(){ 3 System.out.println("testDefaultHandlerExceptionResolver..."); 4 return "success"; 5 }
2.在jsp页面发送请求
1 <a href="testDefaultHandlerExceptionResolver">Test DefaultHandlerExceptionResolver</a>
五、SimpleMappingExceptionResolver
如果希望对所有异常进行统一处理,可以使用SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
1. 在springmvc.xml配置SimpleMappingExceptionResolver,配置异常的名字exceptionAttribute和异常回显的页面exceptionMappings
1 <!-- 配置使用 SimpleMappingExceptionResolver 来映射异常 --> 2 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 3 <property name="exceptionAttribute" value="ex"></property> 4 <property name="exceptionMappings"> 5 <props> 6 <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop> 7 </props> 8 </property> 9 </bean>
2. 编写handle
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 }
3.在jsp页面发送请求
1 <a href="testSimpleMappingExceptionResolver?i=12">Test SimpleMappingExceptionResolver</a>
4.错误回显页面error.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 11 <h4>Error Page</h4> 12 13 ${requestScope.ex } 14 15 </body> 16 </html>