目录
1.问题描述
在讲解这一部分知识点之前,我们先来演示个效果,修改BookController类的getById
方法
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
//手动添加一个错误信息
if(id==1){
int i = 1/0;
}
Book book = bookService.getById(id);
Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
String msg = book != null ? "" : "数据查询失败,请重试!";
return new Result(code,book,msg);
}
重新启动运行项目,使用PostMan发送请求,当传入的id为1,则会出现如下效果:
前端接收到这个信息后和之前我们约定的格式不一致,这个问题该如何解决?
在解决问题之前,我们先来看下异常的种类及出现异常的原因:
-
框架内部抛出的异常:因使用不合规导致
-
数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)
-
业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等)
-
表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常)
-
工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)
看完上面这些出现异常的位置,你会发现,在我们开发的任何一个位置都有可能出现异常,而且这些异常是不能避免的。所以我们就得将异常进行处理。
思考
-
各个层级均出现异常,异常处理代码书写在哪一层?
==所有的异常均抛出到表现层进行处理==
-
异常的种类很多,表现层如何将所有的异常都处理到呢?
==异常分类==
-
表现层处理异常,每个方法中单独书写,代码书写量巨大且意义不强,如何解决?
==AOP==
对于上面这些问题及解决方案,SpringMVC已经为我们提供了一套解决方案:
-
异常处理器:
-
集中的、统一的处理项目中出现的异常。
-
2.异常处理器的使用
2.1 环境准备
-
创建一个Web的Maven项目
-
pom.xml添加SSM整合所需jar包
-
创建对应的配置类
-
编写Controller、Service接口、Service实现类、Dao接口和模型类
-
resources下提供jdbc.properties配置文件
最终创建好的项目结构如下:
使用步骤
步骤1:创建异常处理器类
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
@ExceptionHandler(Exception.class)
public void doException(Exception ex){
System.out.println("嘿嘿,异常你哪里跑!")
}
}
==确保SpringMvcConfig能够扫描到异常处理器类==
步骤2:让程序抛出异常
修改BookController
的getById方法,添加int i = 1/0
.
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
int i = 1/0;
Book book = bookService.getById(id);
Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
String msg = book != null ? "" : "数据查询失败,请重试!";
return new Result(code,book,msg);
}
步骤3:运行程序,测试
说明异常已经被拦截并执行了doException
方法。
异常处理器类返回结果给前端
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
System.out.println("嘿嘿,异常你哪里跑!")
return new Result(666,null,"嘿嘿,异常你哪里跑!");
}
}
启动运行程序,测试
至此,就算后台执行的过程中抛出异常,最终也能按照我们和前端约定好的格式返回给前端。
知识点1:@RestControllerAdvice
名称 | @RestControllerAdvice |
---|---|
类型 | ==类注解== |
位置 | Rest风格开发的控制器增强类定义上方 |
作用 | 为Rest风格开发的控制器类做增强 |
说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能
知识点2:@ExceptionHandler
名称 | @ExceptionHandler |
---|---|
类型 | ==方法注解== |
位置 | 专用于异常处理的控制器方法上方 |
作用 | 设置指定异常的处理方案,功能等同于控制器方法, 出现异常后终止原始控制器执行,并转入当前方法执行 |
说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常