首先在SpringMVC中加上<mvc:annotation-driven>标签:
<mvc:annotation-driven></mvc:annotation-driven>
新建一个error.jsp页面
1、基于注解的异常处理
(1)@ExceptionHandler注解
在当前Handler中定义由@ExceptionHandler注解修饰的方法,用于处理当前Handler中的异常信息!
在Handler中定义如下方法:
1 @ExceptionHandler(value={ArithmeticException.class}) 2 public String handleException(){ 3 System.out.println("ExceptionHandler====ArithmeticException======="); 4 return "error"; 5 } 6 @ExceptionHandler(value={Exception.class})//value为对应的异常信息,异常的字节码文件,可定义多个 7 public String handleException1(){ 8 System.out.println("ExceptionHandler====ArithmeticException======="); 9 return "error"; 10 } 11 @RequestMapping(value="/test",method=RequestMethod.GET) 12 public String testException(@RequestParam(value="i") Integer i){ 13 int j= 10/i; 14 return "success"; 15 }
成功则返回success.jsp,失败则返回error.jsp
注意:
①@ExceptionHandler方法修饰的入参中可以加入Exception类型的参数,该参数即对应发生的异常信息
②@ExceptionHandler方法的入参中不能传入Map,也不能使用model。若希望把异常信息传到页面上,需要使用ModelAndView作为方法的返回值。
1 @ExceptionHandler(value={ArithmeticException.class}) 2 public ModelAndView handleException(Exception ex){ 3 System.out.println("ExceptionHandler====ArithmeticException======="); 4 ModelAndView mv=new ModelAndView(); 5 mv.addObject("ex", ex); 6 mv.setViewName("error"); 7 return mv; 8 }
在error.jsp页面用${ex }获取返回值。java.lang.ArithmeticException: / by zero
优先级问题
①当有两个异常处理时,优先走精确的,例如上面定义了异常,
ArithmeticException和Exception
当发生ArithmeticException异常时,会优先走ArithmeticException的处理方法,输出
ExceptionHandler====ArithmeticException=======
②如果在上面定义的方法中,将ArithmeticException.class改为RuntimeException.class,也就是声明了 RuntimeException 和 Exception,此时在发生ArithmeticException时,
会根据异常的最近继承关系找到继承深度最浅的那个,也就是会走 RuntimeException 的异常处理方法。
注:(如果将ArithmeticException换成NullPointerException,此时在发生ArithmeticException时,会走Exception的处理方法,和继承深度有关系,没理解好)
(2)@ControllerAdvice注解
自定义Handler类,所有的Handler类出现的异常都会经过此类中的方法
1 @ControllerAdvice 2 public class MyException { 3 @ExceptionHandler(value=Exception.class) 4 public String HandleException(){ 5 System.out.println("ControllerAdvice====Exception======="); 6 return "error"; 7 } 8 @ExceptionHandler(value={ArithmeticException.class}) 9 public String handleException(){ 10 System.out.println("ControllerAdvice====ArithmeticException======="); 11 return "error"; 12 } 13 }
需要注意的问题和优先级问题与(1)中一样。
另外需要注意的是:当两种情况(1)(2)并存时,发生异常会优先走本类中的异常处理方法。
2、基于配置的异常处理
如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
在springmvc中配置
1 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 2 <!-- 指定在在request域中获取异常信息所需要的key:即ex,默认是exception --> 3 <property name="exceptionAttribute" value="ex"></property> 4 <!-- 指定异常映射 --> 5 <property name="exceptionMappings"> 6 <props> 7 <!-- 由prop标签的key属性指定发生异常的全类名,由值指定出现异常去哪个页面! --> 8 <prop key="java.lang.ArithmeticException">error</prop> 9 </props> 10 </property> 11 </bean>
在error.jsp页面用${ex }可以获取到异常名。java.lang.ArithmeticException: / by zero
基于注解比基于配置优先级高。