Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。
SpringMVC 提供的 HandlerExceptionResolver 的实现类:
1.HandlerExceptionResolver
DispatcherServlet 默认装配的 HandlerExceptionResolver
2.ExceptionHandlerExceptionResolver
主要处理 Handler 中用 @ExceptionHandler
注解定义的方法。
• @ExceptionHandler 注解定义的方法优先级问题:例如发生的是 ArithmeticException,但是声明的异常有 RuntimeException 和 ArithmeticException,此候会根据异常的最近继承关系找到继承深度最浅的那个 @ExceptionHandler 注解方法,即标记了 ArithmeticException 的方法
测试代码:
Jsp 页面:<a href="testExceptionHandlerExcepitonResolver?i=10">Test ExceptionHandlerExcepitonResolver</a>
先后测试 i=10,i=0;当 i=0 的时候,发生异常/
SpringMVCTest 页面:
/*
* 1.在@ExceptionHandler 方法的入参中可以加入 Exception 类型的参数,该参数即对应发生的异常对象
* 2. @ExceptionHandler 方法的入参不能传入Map.若希望把异常信息传导页面上,需要使用 ModelAndView 作为返回值
* 3. @ExceptionHandler 方法标记的异常有优先级的问题
* */
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handleArithmeticException(Exception ex){
System.out.println("异常方法1ex:"+ex);
ModelAndView mv =new ModelAndView("error");
mv.addObject("Exception",ex);
return mv;
}
@ExceptionHandler({RuntimeException.class})
public ModelAndView handleArithmeticException2(Exception ex){
System.out.println("异常方法2Ex:"+ex);
ModelAndView mv =new ModelAndView("error");
mv.addObject("Exception",ex);
return mv;
}
@RequestMapping("/testExceptionHandlerExcepitonResolver")
public String TestExceptionHandlerExcepitonResolver(@RequestParam("i") int i){
System.out.println("result:"+10/i);
return "success";
}
ExceptionHandlerMethodResolver 内部若找不到 @ExceptionHandler 注解的话,会找 @ControllerAdvice 中的 @ExceptionHandler 注解方法.
通俗来说,就是当 SpringMVCTest 中没有定义异常 @ExceptionHandler 注解的话,会去同一个包别的页面找 @ControllerAdvice 中的 @ExceptionHandler 注解方法.
eg:在 SpringMVCTest 包下创建一个 SpringMVCTestExceptionHandler
代码如下:
package com.SpringMVC.Test;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
public class HandleException {
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handleArithmeticException(Exception ex){
System.out.println("---->ex:"+ex);
ModelAndView mv =new ModelAndView("error");
mv.addObject("Exception",ex);
return mv;
}
@ExceptionHandler({RuntimeException.class})
public ModelAndView handleArithmeticException2(Exception ex){
System.out.println("RuntimeEx:"+ex);
ModelAndView mv =new ModelAndView("error");
mv.addObject("Exception",ex);
return mv;
}
}
当在 SpringMVCTest 中找不到 @ExceptionHandler 注解 就会去同包类下寻找 SpringMVCTestExceptionHandler 页面是否有 @ControllerAdvice 中的 @ExceptionHandler 注解方法.
3.ResponseStatusExceptionResolver
在异常及异常父类中找到 @ResponseStatus
注解,然后使用这个注解的属性进行处理
• 定义一个 @ResponseStatus
注解修饰的异常类 UserAndPasswordNullMatch
@ResponseStatus(value=HttpStatus.NOT_FOUND,reason="用户名和密码不匹配")
public class UserAndPasswordNullMatch extends RuntimeException {
private static final long serialVersionUID = 1L;
}
然后 jsp 页面:<a href="testResponseStatusException?i=10">Test ResponseStatusException?i=10</a>
SpringMVCTest 页面:i 的值为 13 的时候抛出自定义异常
@RequestMapping("/testResponseStatusException")
public String testResponseStatusException(@RequestParam("i") int i){
if(i==13){
throw new UserAndPasswordNullMatch();
}
System.out.println("testResponseStatusException....");
return "success";
}
效果图:
如果在 SpringMVCTest 页面方法上直接使用 @ResponseStatus
eg:
@ResponseStatus(value=HttpStatus.UNAUTHORIZED,reason="直接方法上面加ResponseStatus测试")
@RequestMapping("/testResponseStatusException")
public String testResponseStatusException(@RequestParam("i") int i){
if(i==13){
throw new UserAndPasswordNullMatch();
}
System.out.println("testResponseStatusException....");
return "success";
}
然后你无论输入的 i 的任何值,都返回异常
4.DefaultHandlerExceptionResolver
比如 NoSuchRequestHandlingMethodException、HttpRequestMethodNotSupportedException、HttpMediaTypeNotSupportedException、HttpMediaTypeNotAcceptableException 等
5.SimpleMappingExceptionResolver
如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常.
需要在 SpringMVC.xml 下配置
<!-- 配置 SimpleMappingExceptionResolver -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionAttribute" value="ex"></property><!-- 定义请求域中异常的名称,用于界面显示 -->
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
error.jsp 页面:
<body>
You error!
<br/><br/>
${requestScope.ex }
</body>
显示效果:
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于