9. 异常处理

空~2022年9月15日
  • SpringMVC
大约 3 分钟

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>