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

Spring Boot 项目统一异常处理

在 Spring Boot 项目开发中,异常处理是一个非常重要的环节。良好的异常处理不仅能提高应用的健壮性,还能提升用户体验。本文将介绍如何在 Spring Boot 项目中实现统一异常处理。

统一异常处理有以下几个优点:

  1. 提高代码可维护性:异常处理逻辑集中管理,减少了代码的冗余和分散。
  2. 提升用户体验:用户能看到一致且友好的错误信息,而不是杂乱的堆栈跟踪。
  3. 安全性:避免将敏感的错误信息暴露给用户。

使用 @ControllerAdvice 和 @ExceptionHandler 实现统一异常处理

Spring 提供了 @ControllerAdvice 注解用于集中处理控制器层的全局异常。@ExceptionHandler 注解用于定义具体的异常处理方法。下面是一个基本的示例:

1. 创建异常处理类

首先,我们创建一些自定义异常处理类,以便可以捕捉到controller中出现的异常,防止直接报给前端500的错误码:

@ControllerAdvice //添加完此注解后,此类随着springboot项目的启动而启动,并且会监控controller的异常.监听项目中所有的异常
@ResponseBody
public class MyExceptionAdvice {//这里的一场都是意外异常,并不是业务异常,业务异常后端controller会处理返回给前端.业务异常会和前端沟通好已规定的状态码返回。@ExceptionHandler(NullPointerException.class)public HashMap<String,Object> doNullPointerException(NullPointerException e){HashMap<String, Object> res = new HashMap<>();res.put("code",-1);res.put("msg","空指针异常"+e.getMessage());res.put("data",null);return res;}// 默认的异常处理,当有有异常出现的时候,会先匹配子类的异常,当所有的异常都没有匹配的时候就会走这一条默认的一场路线业务。@ExceptionHandler(Exception.class)public HashMap<String,Object> doException(Exception e){HashMap<String, Object> res = new HashMap<>();res.put("code",-1);res.put("msg","异常"+e.getMessage());res.put("data",null);return res;}
}

 使用@ExceptionHandler 注解的时候,需要传入异常类。使用注解的方法名和返回值都可以自定义,但是传入的变量要和注解中传入的异常类保持一致。

我们也不可能将所有可能出现的异常都列举出来,那该怎么办呢?我们只需要针对所有异常类的父类Exception进行异常处理即可

 2. 触发异常观察结果

controller代码:

我们现在访问 http://127.0.0.1:8080/user/login :

 确实通过AOP的思想捕获到项目中出现的异常了,并且代码完全没有侵入到项目的业务代码中。

如果我们不进行这些异常处理会是怎么样的结果,我们注解去掉注解让异常处理失效,再次访问login,观察结果:

这样的结果并不是优秀的项目该有的,显得和挫啊。


总结

统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,@ControllerAdvice 表示控制器通知类,@ExceptionHandler 是异常处理器,两个结合表示当出现异常的时候执⾏某个通知, 也就是执⾏某个⽅法事件。

相关文章:

  • netplan
  • Visual Studio 的调试(一)
  • 42-4 应急响应之文件痕迹排查
  • Rust面试宝典第14题:旋转数组
  • Redis教程(十三):Redis的主从复制模式搭建
  • 【论文阅读】Prompt Fuzzing for Fuzz Driver Generation
  • 设计模式-中介者模式
  • SpringBoot+Mybatis 从头搭建通用管理系统
  • Linux环境下TensorFlow安装教程
  • 简单多状态 dp 问题
  • Facebook广告如何开户以及投放费用?
  • MySQL中创建触发器时,语法与创建存储过程或函数的语法有所不同注意
  • RobotFramework测试框架(1)--官网示例
  • ACM实训冲刺第十九天
  • Vue.js组件设计模式:构建可复用组件库
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 【刷算法】从上往下打印二叉树
  • 4个实用的微服务测试策略
  • flask接收请求并推入栈
  • golang中接口赋值与方法集
  • linux安装openssl、swoole等扩展的具体步骤
  • Next.js之基础概念(二)
  • SQLServer之创建数据库快照
  • 半理解系列--Promise的进化史
  • 初探 Vue 生命周期和钩子函数
  • 普通函数和构造函数的区别
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 实现菜单下拉伸展折叠效果demo
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 再谈express与koa的对比
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​批处理文件中的errorlevel用法
  • (1)STL算法之遍历容器
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (ibm)Java 语言的 XPath API
  • (java)关于Thread的挂起和恢复
  • (Java入门)抽象类,接口,内部类
  • (搬运以学习)flask 上下文的实现
  • (笔试题)分解质因式
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (七)Flink Watermark
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)进入MySQL 【事务】
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • .NET Micro Framework初体验(二)
  • .NET 命令行参数包含应用程序路径吗?
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET/C# 使用 SpanT 为字符串处理提升性能