异常处理
SpringMVC: HandlerExceptionResolver接口,
该接口的每个实现类 都是异常的一种处理方式:
1.ExceptionHandlerExceptionResolver: 主要提供了@ExceptionHandler注解,并通过该注解处理异常
1)异常处理路径:最短优先
如果有方法抛出一个ArithmeticException异常,而该类中有2个对应的异常处理方法:
@ExceptionHandler({Exception.class })
public ModelAndView handlerArithmeticException2(Exception e) {}
@ExceptionHandler({ArithmeticException.class })
public ModelAndView handlerArithmeticException1(Exception e) {}
则优先级: 最短优先。就是离异常发生的程序距离最短的优先。
2)@ExceptionHandler默认只能捕获当前类中的异常方法。
如果发生异常的方法 和处理异常的方法 不在同一个类中:@ControllerAdvice
总结:如果一个方法用于处理异常,并且只处理当前类中的异常:@ExceptionHandler
如果一个方法用于处理异常,并且处理所有类中的异常:
i 类前加@ControllerAdvice
ii 处理异常的方法前加@ExceptionHandler
2.ResponseStatusExceptionResolver:自定义异常显示页面 @ResponseStatus
举例如下:
@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="数组越界233")
public class MyArrayIndexOutofBoundsException extends Exception {//自定义异常
}
@RequestMapping("testMyException")
public String testMyException(@RequestParam("i") Integer i) throws MyArrayIndexOutofBoundsException {
if(i == 3) {
throw new MyArrayIndexOutofBoundsException();//抛出异常
}
return "success" ;
}
@RequestMapping("testMyException2")
public String testMyException2(@RequestParam("i") Integer i) {
if(i == 3) {
return "redirect:testResponseStatus" ;//跳转到某一个 异常处理方法里
}
return "success" ;
}
3.异常处理的实现类:
DefaultHandlerExceptionResolver:SPringMVC在一些常见异常的基础上(300 500 405),新增了一些异常,例如:
* @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
* @see #handleNoSuchRequestHandlingMethod
* @see #handleHttpRequestMethodNotSupported :如果springmvc的处理方法限制为post方式,如果实际请求为get,则会触发此异常显示的页面
* @see #handleHttpMediaTypeNotSupported
* @see #handleMissingServletRequestParameter
* @see #handleServletRequestBindingException
* @see #handleTypeMismatch
* @see #handleHttpMessageNotReadable
* @see #handleHttpMessageNotWritable
* @see #handleMethodArgumentNotValidException
* @see #handleMissingServletRequestParameter
* @see #handleMissingServletRequestPartException
* @see #handleBindException
4.SimpleMappingExceptionResolver:通过配置来实现异常的处理
如果发生异常,异常对象会被保存在 exceptionAttribute的value值中;并且会放入request域中 ;异常变量的默认值是 exception
<!-- SimpleMappingExceptionResolver:以配置的方式 处理异常 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 如果发生异常,异常对象会被保存在 exceptionAttribute的value值中;并且会放入request域中 ;异常变量的默认值是 exception-->
<!--<property name="exceptionAttribute" value="exception"></property>-->
<property name="exceptionMappings">
<props>
<!-- 相当于catch(ArithmeticException ex){ 跳转:error } -->
<prop key="java.lang.ArithmeticException">
error
</prop>
<prop key="java.lang.NullPointerException">
error
</prop>
</props>
</property>
</bean>
注意事项:
(1)&&这里用了Resolver,只需要<mvc:annotation-driven>即可,不需要特别配置解析器。
//该方法 可以捕获本类中 抛出的ArithmeticException异常
@ExceptionHandler({ArithmeticException.class,ArrayIndexOutOfBoundsException.class })
public String handlerArithmeticException(Exception e) {
System.out.println(e +"============");
return "error" ;
}
&&这里开始卡了很久,Exception e和ArighmeticException e;
(2)@ExceptionHandler标识的方法的参数 必须在异常类型(Throwable或其子类) ,不能包含其他类型的参数。
public String handlerArithmeticException(Exception e) {
...
}
如果需要传参数,比如需要传异常类型时可以使用ModelAndView:
//该方法可以在本类中捕获对应名称的异常 ArithmeticException
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handlerArithmeticException(ArithmeticException e) {
ModelAndView mv = new ModelAndView("error");//要跳转的页面
mv.addObject("er", e);//要传的参数的key
return mv;
}