一、前言
异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。
二、异常分类
JDK 中定义了很多异常类,这些类对应了各种各样可能出现的异常事件,所有异常对象都是派生于Throwable
类的一个实例。如果内置的异常类不能够满足需要,还可以创建自己的异常类。
Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable
,Throwable
下面又派生了两个子类:Error
和Exception
。我们常用的就是Exception
(也是目前我主要接触的)。
当然我们也可以自定义异常类让该类继承Exception
。
三、在Spring Boot项目开发中异常的处理
在项目开发过程中异常处理的方法有很多,在这里说一下SpringMVC
里使用@ExceptionHandler
注解处理异常的方法。
使用注解@ExceptionHandler
可以将一个方法指定为异常处理方法。该注解只有一个可选属性value
,为一个Class<?>
数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。
而被注解的方法,其返回值可以是ModelAndView
、String
,或 void
,方法名随意,方法参数可以是Exception
及其子类对象、HttpServletRequest
、HttpServletResponse
等。系统会自动为这些方法参数赋值。
1、首先定义一个自定义异常类将其HTTP响应的状态码设置为NOT_FOUND
并重写其父类重要的三个方法。
//将自定义异常类状态码设置为NOT_FOUND
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
super();
}
public NotFoundException(String message) {
super(message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
2、定义异常处理类
这里用到@ControllerAdvice
注解:字面理解就是“控制器增强”,是给控制器对象增强功能的。使用@ControllerAdvice
修饰的类中可以使用@ExceptionHandler
。目的是将异常处理方法集中在一个类中。
@ControllerAdvice
public class ControllerException {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(HttpServletRequest request,Exception e) throws Exception {
//将日志打印输出到页面源代码
logger.error("Request URL : {},Exception : {}",request.getRequestURL(),e);
//判断状态码是否为空
if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null){
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception",e);
mv.setViewName("error/error.html");
return mv;
}
}
当下面程序抛出异常时,若异常类型为NotFoundException
则交给Spring Boot自行解决,Spring Boot会根据状态码找到对应的页面(可自定义在thymeleaf文件夹下)返回,其他则跳转到error页面
@Controller
public class indexController {
@GetMapping("/")
public String index(){
// int a = 9 / 0;
String blog = null;
if(blog == null){
throw new NotFoundException("博客不存在");
}
return "index";
}
}