9. 异常处理
2022年9月15日
9. 异常处理
@ExceptionHandler 注解:
使用注解@ExceptionHandler 可以将一个方法指定为异常处理方法。
该注解只有一个可选属性 value,为一个 Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。
而被注解的方法,其返回值可以是 ModelAndView、String,或 void,方法名随意,方法参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会自动为这些方法参数赋值。
对于异常处理注解的用法,也可以直接将异常处理方法注解于 Controller 之中。
自定义异常类
定义三个异常类:NameException、AgeException、MyUserException。其中 MyUserException 是另外两个异常的父类。
- MyUserException
public class MyUserException extends Exception {
public MyUserException() {
super();
}
public MyUserException(String message) {
super(message);
}
}
- NameException
//表示当用户的姓名有异常,抛出NameException
public class NameException extends MyUserException {
public NameException() {
super();
}
public NameException(String message) {
super(message);
}
}
- AgeException
//当年龄有问题时,抛出的异常
public class AgeException extends MyUserException {
public AgeException() {
super();
}
public AgeException(String message) {
super(message);
}
}
创建一个普通类, 作用全局异常处理类
@ControllerAdvice:
控制器增强(也就是说给控制器类增加功能--异常处理功能)
位置:在类的上面。
特点:必须让框架知道这个注解所在的包名,需要在 springmvc 配置文件声明组件扫描器。指定**@ControllerAdvice**所在的包名
定义方法,处理发生的异常
处理异常的方法和控制器方法的定义一样, 可以有多个参数, 可以有 ModelAndView, String, void 和对象类型的返回值
形参: Exception, 表示 Controller 中抛出的异常对象。通过形参可以获取发生的异常信息。
@ExceptionHandler(异常的 class)
表示异常的类型, 当发生此类型异常时, 由该方法处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = NameException.class)
public ModelAndView doNameException(Exception exception){
//处理NameException的异常。
/*
异常发生处理逻辑:
1.需要把异常记录下来, 记录到数据库,日志文件。
记录日志发生的时间,哪个方法发生的,异常错误内容。
2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。
3.给用户友好的提示。
*/
ModelAndView mv = new ModelAndView();
mv.addObject("msg","姓名必须是zs,其它用户不能访问");
mv.addObject("ex",exception);
mv.setViewName("nameError");
return mv;
}
//处理AgeException
@ExceptionHandler(value = AgeException.class)
public ModelAndView doAgeException(Exception exception){
//处理AgeException的异常。
/*
异常发生处理逻辑:
1.需要把异常记录下来, 记录到数据库,日志文件。
记录日志发生的时间,哪个方法发生的,异常错误内容。
2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。
3.给用户友好的提示。
*/
ModelAndView mv = new ModelAndView();
mv.addObject("msg","你的年龄不能大于80");
mv.addObject("ex",exception);
mv.setViewName("ageError");
return mv;
}
//处理其它异常, NameException, AgeException以外,不知类型的异常
@ExceptionHandler
public ModelAndView doOtherException(Exception exception){
//处理其它异常
ModelAndView mv = new ModelAndView();
mv.addObject("msg","你的年龄不能大于80");
mv.addObject("ex",exception);
mv.setViewName("defaultError");
return mv;
}
}
在 springmvc 配置文件声明组件扫描器。指定 @ControllerAdvice 所在的包名
<!--声明组件扫描器指定controller(@Controller所在的包名)-->
<context:component-scan base-package="com.bjpowernode.controller" />
<!--声明组件扫描器指定handler(@ControllerAdvice所在的包名)-->
<context:component-scan base-package="com.bjpowernode.handler" />
<!--注解驱动-->
<mvc:annotation-driven />
修改 Controller 抛出异常
@RequestMapping(value = "/some.do")
public ModelAndView doSome(String name,Integer age) throws MyUserException {
ModelAndView mv = new ModelAndView();
if (!"zs".equals(name)) {
throw new NameException("姓名不正确!!!");
}
if (age == null || age > 80) {
throw new AgeException("年龄比较大!!!");
}
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("show");
return mv;
}
定义异常响应页面
- ageError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
ageError.jsp <br/>
提示信息:${msg} <br/>
系统异常消息:${ex.message}
</body>
</html>
- nameError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
nameError.jsp <br/>
提示信息:${msg} <br/>
系统异常消息:${ex.message}
</body>
</html>
- defaultError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
defaultError.jsp <br/>
提示信息:${msg} <br/>
系统异常消息:${ex.message}
</body>
</html>