当前位置: 首页 > news >正文

Javaweb之SpringBootWeb案例之异常处理功能的详细解析

3. 异常处理

3.1 当前问题

登录功能和登录校验功能我们都实现了,下面我们学习下今天最后一块技术点:异常处理。首先我们先来看一下系统出现异常之后会发生什么现象,再来介绍异常处理的方案。

我们打开浏览器,访问系统中的新增部门操作,系统中已经有了 "就业部" 这个部门,我们再来增加一个就业部,看看会发生什么现象。

点击确定之后,窗口关闭了,页面没有任何反应,就业部也没有添加上。 而此时,大家会发现,网络请求报错了。

状态码为500,表示服务器端异常,我们打开idea,来看一下,服务器端出了什么问题。

上述错误信息的含义是,dept部门表的name字段的值 就业部 重复了,因为在数据库表dept中已经有了就业部,我们之前设计这张表时,为name字段建议了唯一约束,所以该字段的值是不能重复的。

而当我们再添加就业部,这个部门时,就违反了唯一约束,此时就会报错。

我们来看一下出现异常之后,最终服务端给前端响应回来的数据长什么样。

响应回来的数据是一个JSON格式的数据。但这种JSON格式的数据还是我们开发规范当中所提到的统一响应结果Result吗?显然并不是。由于返回的数据不符合开发规范,所以前端并不能解析出响应的JSON数据。

接下来我们需要思考的是出现异常之后,当前案例项目的异常是怎么处理的?

  • 答案:没有做任何的异常处理

当我们没有做任何的异常处理时,我们三层架构处理异常的方案:

  • Mapper接口在操作数据库的时候出错了,此时异常会往上抛(谁调用Mapper就抛给谁),会抛给service。

  • service 中也存在异常了,会抛给controller。

  • 而在controller当中,我们也没有做任何的异常处理,所以最终异常会再往上抛。最终抛给框架之后,框架就会返回一个JSON格式的数据,里面封装的就是错误的信息,但是框架返回的JSON格式的数据并不符合我们的开发规范。

3.2 解决方案

那么在三层构架项目中,出现了异常,该如何处理?

  • 方案一:在所有Controller的所有方法中进行try…catch处理

    • 缺点:代码臃肿(不推荐)

  • 方案二:全局异常处理器

    • 好处:简单、优雅(推荐)

3.3 全局异常处理器

我们该怎么样定义全局异常处理器?

  • 定义全局异常处理器非常简单,就是定义一个类,在类上加上一个注解@RestControllerAdvice,加上这个注解就代表我们定义了一个全局异常处理器。

  • 在全局异常处理器当中,需要定义一个方法来捕获异常,在这个方法上需要加上注解@ExceptionHandler。通过@ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。

@RestControllerAdvice
public class GlobalExceptionHandler {
​//处理异常@ExceptionHandler(Exception.class) //指定能够处理的异常类型public Result ex(Exception e){e.printStackTrace();//打印堆栈中的异常信息
​//捕获到异常之后,响应一个标准的Resultreturn Result.error("对不起,操作失败,请联系管理员");}
}

@RestControllerAdvice = @ControllerAdvice + @ResponseBody

处理异常的方法返回值会转换为json后再响应给前端

重新启动SpringBoot服务,打开浏览器,再来测试一下添加部门这个操作,我们依然添加已存在的 "就业部" 这个部门:

此时,我们可以看到,出现异常之后,异常已经被全局异常处理器捕获了。然后返回的错误信息,被前端程序正常解析,然后提示出了对应的错误提示信息。

以上就是全局异常处理器的使用,主要涉及到两个注解:

  • @RestControllerAdvice //表示当前类为全局异常处理器

  • @ExceptionHandler //指定可以捕获哪种类型的异常进行处理

http://www.lryc.cn/news/298562.html

相关文章:

  • 苹果Mac键盘如何将 F1 到 F12 取消按Fn
  • linux下ipconfig命令报:command not found 解决方法
  • Android导入其它项目慢,Gradel下载失败,另辟蹊径:使用离线gradle加载,附镜像方式
  • 神经语言程式(NLP)项目的15 个开源训练数据集
  • H5 红色文字抖动网址发布页/引导页源码
  • MacOS - 菜单栏上显示『音量』
  • 深入理解常见的设计模式
  • 服务器解析漏洞及任意文件下载
  • ES6扩展运算符——三个点(...)用法详解
  • 限制资源使用
  • 结合Next项目实际认识webpack.splitChunks
  • 【Tauri】(2):使用Tauri应用开发,使用开源的Chatgpt-web应用做前端,使用rust 的candle做后端,本地运行小模型桌面应用
  • C#where T :通用的泛型约束(generic constraint)语法
  • vue使用Mars3d弹框嵌套video视频/实时视频(m3u8)使用hls.js
  • Python爬虫之Ajax数据爬取基本原理
  • osg操控器和键盘切换操控器学习
  • LeetCode1143. Longest Common Subsequence——动态规划
  • 利用Windows10漏洞破解密码(保姆级教学)
  • apk反编译修改教程系列---简单修改apk默认横竖屏显示 手机端与电脑端同步演示【十一】
  • 2301: 不定方程解的个数
  • vue3学习——封装菜单栏
  • 深度学习的进展及其在各领域的应用
  • blender怎么保存窗口布局,怎么设置默认输出文件夹
  • 【开源】基于JAVA+Vue+SpringBoot的实验室耗材管理系统
  • 【ES】--Elasticsearch的分词器详解
  • 【算法】{画决策树 + dfs + 递归 + 回溯 + 剪枝} 解决排列、子集问题(C++)
  • sqlserver 存储过程
  • C语言什么是悬空指针?
  • AES加密后的密码可以破解吗
  • vue3学习——路由进度条