1. 异常处理概述
- Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。
- SpringMVC 提供的 HandlerExceptionResolver 的实现类
2. HandlerExceptionResolver
DispatcherServlet 默认装配的 HandlerExceptionResolver :
① 没有使用 < mvc:annotation-driven /> 配置:
② 使用了< mvc:annotation-driven /> 配置
3. 实验代码
①页面链接
<a href="testExceptionHandlerExceptionResolver?i=1">testExceptionHandlerExceptionResolver</a>
②控制器方法
@Controller
public class ExceptionHandler {
@RequestMapping("/testExceptionHandlerExceptionResolver")
public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i){
System.out.println("10/"+i+"="+(10/i));
return "success";
}
}
③测试,出现异常情况
处理异常,跳转到error.jsp
④在控制器中增加处理异常的方法
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public String handleException(Exception ex){
System.out.println("出现异常啦"+ex);
return "error";
}
⑤增加error.jsp
<h3>Error Page</h3>
4. 如何将异常对象从控制器携带给页面,做异常信息的获取
① 异常对象不能通过Map集合方式传递给成功页面。(Map不可以)
// @ExceptionHandler(value={java.lang.ArithmeticException.class})
public String handleException(Exception ex,Map<String,Object> map){
System.out.println("出现异常啦:"+ex);
map.put("exception",ex);
return "error";
}
②可以通过ModelAndView将异常对象传递给成功页面上
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
//视图解析器拼串
return mv;
}
5. 匹配异常类型,执行顺序问题
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
@ExceptionHandler(value={java.lang.RuntimeException.class})
public ModelAndView handleException2(Exception ex){
System.out.println("RuntimeException-出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
6. 公共的处理异常的类@ControllerAdvice
定义公共的处理异常的类
@ControllerAdvice
public class ExceptionAdviceHandler {
/*
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public ModelAndView handleException(Exception ex){
System.out.println("出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}*/
@ExceptionHandler(value={java.lang.RuntimeException.class})
public ModelAndView handleException2(Exception ex){
System.out.println("RuntimeException-出现异常啦:"+ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
}
7. ExceptionHandlerExceptionResolver
主要处理 Handler 中用 @ExceptionHandler 注解定义的方法。
@ExceptionHandler 注解定义的方法优先级问题:例如发生的是NullPointerException,但是声明的异常有 RuntimeException 和 Exception,此候会根据异常的最近继承关系找到继承深度最浅的那个 @ExceptionHandler 注解方法,即标记了 RuntimeException 的方法
ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话,会找 @ControllerAdvice 中的@ExceptionHandler 注解方法
8. 异常处理_ResponseStatusExceptionResolver
在异常及异常父类中找到 @ResponseStatus 注解,然后使用这个注解的属性进行处理。
定义一个 @ResponseStatus 注解修饰的异常类
若在处理器方法中抛出了上述异常:若ExceptionHandlerExceptionResolver 不解析上述异常。由于触发的异常 UnauthorizedException 带有@ResponseStatus 注解。因此会被ResponseStatusExceptionResolver 解析到。最后响应HttpStatus.UNAUTHORIZED 代码给客户端。HttpStatus.UNAUTHORIZED 代表响应码401,无权限。 关于其他的响应码请参考 HttpStatus 枚举类型源码。
① 页面链接 ```html testResponseStatusExceptionResolver
② 自定义异常类
```java
/**
* 自定义异常类
HttpStatus.FORBIDDEN 不允许的,禁用的
*/
@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户名称和密码不匹配")
public class UsernameNotMatchPasswordException extends RuntimeException{
}
[
](https://blog.csdn.net/qq_43284469/article/details/111205605)
③控制器方法
@RequestMapping(value="/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if(i==13){
throw new UsernameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver...");
return "success";
}
④ 出现的错误消息
- 没使用注解时:@ResponseStatus(value=HttpStatus.FORBIDDEN,reason=“用户名称和密码不匹配”)
- 用注解时:@ResponseStatus(value=HttpStatus.FORBIDDEN,reason=“用户名称和密码不匹配”
- 测试在方法上使用注解
```java
@ResponseStatus(value=HttpStatus.NOT_FOUND,reason=”测试方法上设置响应状态码”)
@RequestMapping(value=”/testResponseStatusExceptionResolver”)
public String testResponseStatusExceptionResolver(@RequestParam(“i”) int i){
if(i==13){
} System.out.println(“testResponseStatusExceptionResolver…”); return “success”; }throw new UsernameNotMatchPasswordException();

<a name="u96kn"></a>
## 9. 异常处理_DefaultHandlerExceptionResolver
- 对一些特殊的异常进行处理,比如:
- NoSuchRequestHandlingMethodException、
- HttpRequestMethodNotSupportedException、
- HttpMediaTypeNotSupportedException、
- HttpMediaTypeNotAcceptableException等。
<a name="SAokt"></a>
##
① 增加页面链接:GET请求
```html
<a href="testDefaultHandlerExceptionResolver">testDefaultHandlerExceptionResolver</a>
增加处理器方法
//@RequestMapping(value="/testDefaultHandlerExceptionResolver")
@RequestMapping(value="/testDefaultHandlerExceptionResolver",method=RequestMethod.POST) //不支持GET请求
public String testDefaultHandlerExceptionResolver(){
System.out.println("testDefaultHandlerExceptionResolver...");
return "success";
}
② 出现异常错误
10. 异常处理_SimpleMappingExceptionResolver
- 如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
① 增加页面链接
<a href="testSimpleMappingExceptionResolver?i=1">testSimpleMappingExceptionResolver</a>
② 增加控制器方法
@RequestMapping("/testSimpleMappingExceptionResolver")
public String testSimpleMappingExceptionResolver(@RequestParam("i") int i){
System.out.println("testSimpleMappingExceptionResolver...");
String[] s = new String[10];
System.out.println(s[i]);
return "success";
}
③ 出现异常情况:参数i的值大于10
④ 配置异常解析器:自动将异常对象信息,存放到request范围内
<!-- 配置SimpleMappingExceptionResolver异常解析器 -->
<bean id="simpleMappingExceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- exceptionAttribute默认值(通过ModelAndView传递给页面):
exception -> ${requestScope.exception}
public static final String DEFAULT_EXCEPTION_ATTRIBUTE = "exception";
-->
<property name="exceptionAttribute" value="exception"></property>
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>Error Page</h3>
${exception }
${requestScope.exception }
</body>
</html>