系列文章目录
Java后端开发功能模块思路
Spring Boot自动配置–如何切换内置Web服务器
Spring Boot读取配置文件内容的三种方式
该系列文章持续更新,更多的文章请点击我的主页查看哦!
文章目录
- 系列文章目录
- 前言
- 一、出现的问题
- 二、解决问题的方法
- 1. 添加前先查询(不推荐)
- 2. 抛出局部异常(不推荐)
- 3.全局异常处理 (推荐)
- 三、解决问题
- 四、效果展示
- 五、全部代码
- 总结
前言
在我们开发项目的过程中难免会遇到要抛出异常,对异常进行处理。该文章我们就来聊聊全局异常处理该怎么做,以及代码如何实现。我们这里用添加员工功能模块的代码来引出问题。一步步的发现问题和解决问题。
一、出现的问题
在我们做添加操作时,如果输入的名称(就像游戏名一样,表的该字段设置为唯一的),如果该名称我们现在数据库表中已经有了这样的名称,那么在做添加操作时就会抛出SQL异常。
如下图所示:意思是“xiaoming”这个在数据库中已存在,并且该字段为唯一字段。所以在添加就添加不进去了,抛出异常。
二、解决问题的方法
1. 添加前先查询(不推荐)
什么是添加前先查询呢?有经验的小伙伴就会想到说:在添加的数据传给服务端后,要先进行对于要添加名称的查询,如果查询的数据库表中有该名称就返回“添加失败”,没有该名称就在执行添加的SQL语句添加到数据库表中。
首先这是可行的操作,也不会在出现什么异常。但是忽略了一个关键的性能问题,如果使用上述说的去编写代码,我们会先查询、后添加。访问2次数据库,对于性能来说是及其不推荐的写法。
2. 抛出局部异常(不推荐)
抛出局部异常,就是在该执行SQL语句上添加try、catch来捕获异常进行抛出。这下就只用执行一次SQL,性能问题上没有什么变化了吧!
但只抛出一个异常还好,如果这类异常情况多了呢,就会出现大量的try、catch来进行异常处理。这样也不是我们想要的。所以我们来看第三种全局异常处理。
3.全局异常处理 (推荐)
全局异常处理就没有了上述的弊端,实现优雅的方式编写代码。代码的可读性也会变高。
三、解决问题
所以我们用全局异常处理解决问题。首先在包下创建一个GlobalExceptionHandler的实现类,在类上添加@ControllerAdvice注解,注解里面使用annotations来确定异常抛出的范围,意思就是哪些类下有异常时会执行该类。
代码如下:
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
上述代码就是将所有以Controller、RestController注解的类抛出的异常都会执行该类进行异常处理。
然后就是编写一个exceptionHandler方法,方法上加注解表示什么类型的异常会执行该方法。这里的话就是SQL异常。里面的异常就是第一张图红色框内的异常信息。函数的参数也是该异常信息。
代码如下:
//抛出SQL异常信息
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
//异常处理
return R.error("添加员工失败");
}
最后就是对这样的异常进行处理逻辑的编写。
首先我们要找到异常中带有Duplicate entry这类异常进行处理。(图一红色框内,英文表示已有该数据,没法添加。)只有这种异常我们才会处理。
代码如下:
//异常中带有Duplicate entry这类异常进行处理
if(ex.getMessage().contains("Duplicate entry")){
String[] split = ex.getMessage().split(" ");
String msg = split[2] + "已存在";
return R.error(msg);
}
上述代码表示如果是该类异常,我们会向前端返回异常【“xiaoming”已存在】。
四、效果展示
我们运行程序,在账号已存在的情况下在进行添加就会抛出【“xiaoming”已存在】。
如下图所示:
五、全部代码
上述的讲解代码是分开的,现在将所有的代码都发上来。供大家参考运用~
/**
* 全局异常处理
* */
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
//抛出SQL异常信息
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
//异常中带有Duplicate entry这类异常进行处理
if(ex.getMessage().contains("Duplicate entry")){
String[] split = ex.getMessage().split(" ");
String msg = split[2] + "已存在";
return R.error(msg);
}
return R.error("添加员工失败");
}
}
总结
全局异常处理是一个很好的方法,可以用来解决这样类似的问题。代码量也不多,大家理解在实际写项目练习时运用上是非常不错的。本篇内容就说到这里,大家如果有什么问题欢迎私信我一起讨论~
如果对这方面的文章该兴趣可以查看我的主页哦~