Java中的全局异常捕获与处理

引言

        Java编程中,异常情况是不可避免的,优秀的异常处理机制是保证程序稳定性和可靠性的重要因素,当程序出现异常的时候,如果没有进行适当的处理,可能导致程序崩溃,丢失数据等严重问题。全局异常捕获与处理可以提高代码可读性,减少代码冗余,利于后期维护,保证系统稳定性。从上篇文章Java中的自定义异常,我们可以看出,如果每个异常单独进行捕获和处理会导致我们产生大量繁琐重复的工作,时间成本也随之增加。本文将深入探讨Java中的全局异常捕获与处理

全局异常捕获与处理原理

        全局异常处理是一种在整个应用程序中捕获和处理异常的机制,它可以捕获没有被处理的异常并进行统一处理。原理:通过在应用程序 的入口点设置异常处理器,来捕获所有未被处理的异常。当程序发生异常时,如果它没有被局部的 try-catch 块捕获并处理,那么它将会被抛出到调用栈的上一层,如果调用栈的任何一层都没有对应的异常处理器,则它最终会被全局异常处理器捕获并进行统一处理

实现全局异常捕获与处理

try-catch

        程序入口点使用 try-catch 块,上一篇文章就是这样处理的,存在代码冗余,耦合度高的问题

注解

        Spring框架提供了@ControllerAdvice和@ExceptionHandler来实现全局异常捕获和处理,@ControllerAdvice用于定义一个全局控制器增强类,@ExceptionHandler用于定义处理特定类型异常的方法,由于我们现在的编程风格是RESTful,所以@ControllerAdvice还需要结合@ResponseBody来使用,或者直接使用@RestControllerAdvice

创建存放处理器的包

创建全局异常处理器

/**
 * 全局异常处理器
 * @author muze
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(CustomException.class)
    public SaResult customException(CustomException customException) {
        // 返回友好提示信息
        return SaResult.error(customException.getMessage());
    }
}

修改用户控制层

        移除自定义异常捕获和处理

/**
 * 用户控制层
 * @author muze
 */
@RestController
@RequestMapping("/user")
public class UserController {
    /**
     * 注入用户业务接口层
     */
    @Autowired
    private IUserService userService;

    /**
     * 登录
     * @param userLoginDTO 用户登录请求实体
     * @return 响应码 + 响应消息 + 响应数据
     */
    @PostMapping("/login")
    public SaResult login(@RequestBody UserLoginDTO userLoginDTO) {
        return SaResult.ok(userService.login(userLoginDTO));
    }
}

修改登录接口实现

        由于我们全局异常捕获和处理中没有打印日志,为了在程序发生异常时快速定位问题,我们在抛出自定义异常前打印日志

/**
 * 用户业务实现层
 * @author muze
 */
//************************  新增日志打印  ************************//
@Slf4j
@Service
public class UserServiceImpl implements IUserService {
    /**
     * 注入用户数据层
     */
    @Autowired
    private UserMapper userMapper;
    @Override
    public String login(UserLoginDTO userLoginDTO) {
        // 取出用户名和密码
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();
        // 构建查询条件
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<User>().eq(User::getUsername, username);
        // 查询用户
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        //************************  新增密码解密  ************************//
        String decryptPassword;
        try {
            decryptPassword = RSAUtil.decryptByPrivateKey(password);
        } catch (Exception e) {
            //************************  打印异常信息  ************************//
            log.error("使用私钥解密密码时异常:", e);
            //************************  抛出自定义异常  ************************//
            throw new CustomException("用户名或密码错误");
        }
        // 如果用户为空或者解密后的输入密码与用户密码不匹配则返回:用户名或密码错误
        if (user == null || !decryptPassword.equals(user.getPassword())) return "用户名或密码错误";
        // 使用SaToken的工具类StpUtil调用登录方法login,入参:用户id
        StpUtil.login(user.getId());
        // 返回:登录成功
        return "登录成功";
    }
}

测试

        运行程序,输入未用公钥加密密码进行登录,程序会在密码解密时抛出自定义异常,控制台和接口调试工具可以看到如下结果

         到这里我们就一起完成了Java中的全局异常捕获和处理,相信你已经掌握了,赶快去试试吧,希望这篇文章能对你有所帮助!

彩蛋:细心的你肯定发现了,我们之前通过SQL插入了一个用户,而不是通过功能实现的,并且密码是明文,下篇文章我们一起实现用户账号注册并通过sha256哈希算法计算出密码的哈希值后入库的功能吧,有兴趣的小伙伴可以先动手试试,敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/939138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Spring Boot的小区车辆管理系统

一、系统背景与目的 随着城市化进程的加快&#xff0c;小区内的车辆数量急剧增加&#xff0c;车辆管理问题日益凸显。传统的车辆管理方式存在效率低、易出错、信息不透明等问题。为了解决这些问题&#xff0c;基于Spring Boot的小区车辆管理系统应运而生。该系统旨在通过信息化…

Mapbox-GL 的源码解读的一般步骤

Mapbox-GL 是一个非常优秀的二三维地理引擎&#xff0c;随着智能驾驶时代的到来&#xff0c;应用也会越来越广泛&#xff0c;关于mapbox-gl和其他地理引擎的详细对比&#xff08;比如CesiumJS&#xff09;&#xff0c;后续有时间会加更。地理首先理解 Mapbox-GL 的源码是一项复…

【计算机网络课程设计】校园网规划与设计

摘要 在科学技术飞速发展的时代&#xff0c;网络互联技术显示出了它蓬勃发展的生命力&#xff0c;它逐渐进入了人们的家居生活&#xff0c;使得当今社会的智能化和网络化越来越来明显。由于Internet的信息和服务内容不断的扩大&#xff0c;使得用户对网络的需求急剧增加。家庭…

单元测试-Unittest框架实践

文章目录 1.Unittest简介1.1 自动化测试用例编写步骤1.2 相关概念1.3 用例编写规则1.4 断言方法 2.示例2.1 业务代码2.2 编写测试用例2.3 生成报告2.3.1 方法12.3.2 方法2 1.Unittest简介 Unittest是Python自带的单元测试框架&#xff0c;适用于&#xff1a;单元测试、Web自动…

【数字化】华为数字化转型架构蓝图

导读&#xff1a;华为的数字化转型规划团队在2016年年底基于对愿景的系统诠释&#xff0c;整合出了数字化转型架构蓝图。该蓝图共分为5层&#xff0c;旨在通过数字化转型实现客户交互方式的转变、作战方式的转变、公司各平台业务能力的数字化、服务化以及运营模式的转变。 目录…

【射频仿真技巧学习笔记】Cadence修改图表背景、曲线颜色

很多初始设置的Cadence仿真出来的曲线是长下面这样的&#xff0c;背景是黑色&#xff0c;而且曲线是Dot点状fine细线&#xff0c;这样查看图像会很不方便 如果一条一条去改曲线的性质会很不方便&#xff0c; 这里我介绍一种方法&#xff0c;只需要输入几行代码就可以自动更改所…

数据结构-排序(来自于王道)

排序的基本概念 插入排序 在这个算法中&#xff0c;除了输入的数组本身&#xff0c;没有使用额外的数据结构来存储数据&#xff0c;所有的操作都是在原数组上进行的。因此&#xff0c;无论输入数组的大小 n 是多少&#xff0c;算法执行过程中所占用的额外空间是固定的&#xff…

zlmediakit搭建直播推流服务

参考连接 夏楚/ZLMediaKit gitee仓库&#xff08;基于C开发的高性能流媒体服务器&#xff09; ZLMediaKit 文档&#xff08;官方文档&#xff09; zlm wiki 维基 ZLMediaKit配置文件详解 ZLMediaKit播放url规则 resultful api web hook EasyPlayer.js 播放器 aizuda/z…

【ELK】Filebeat采集Docker容器日志

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 介绍filebeat是如何工作的 使用部署filebeat 介绍 Filebeat 是一个用于转发和集中日志数据的轻量级传送器。 Filebeat 作为agent安装在服务器上&#xff0c;监视指…

大数据-252 离线数仓 - Airflow 任务调度 Crontab简介 任务集成部署 入门案例

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

鸿蒙快速切换签名配置

鸿蒙快速切换签名配置 参考文档 根据官方签名文档完成签名之后。会在Signing Configs里边生成一个签名项目。 但是因为发布打包这个配置项目是需要手动配置的。那不能开发的时候用自动测试签名&#xff0c;上线的时候还需要手动配置一遍这个吧。想想这么弄就很麻烦。 这个时…

解决git clone时报错“authentication failed for huggingface repository”

问题1&#xff1a; 已经获取了模型的授权&#xff0c;但是git clone时&#xff0c;弹出弹窗 输入huggingface的用户名和密码后&#xff0c;报错如下 解决方式1&#xff1a; 阅读红框标注的说明&#xff0c;“password authentication in git is no longer supported.”&#…

python小课堂(一)

基础语法 1 常量和表达式2 变量和类型2.1 变量是什么2.2 变量语法 3 变量的类型3.1 动态类型特性 4 注释4.1注释是什么 5 输入输出5.1 print的介绍5.2 input 6 运算符6.1 算术运算符在这里插入图片描述6.2 关系运算符6.3 逻辑运算符6.4赋值运算符 1 常量和表达式 在print()中可…

php面对对象的基础知识

php面对对象的基础知识 程序开发&#xff1a;面向过程vs面向对象 面向过程面向过程是一种以“整体事件”为中心的编程思想&#xff0c;编程的时候把解决问题的步骤分析出来&#xff0c;然后用函数把这些步骤实现&#xff0c;在一步一步的具体步骤中再按顺序调用函数。 面向对…

es 开启slowlog

在 Elasticsearch 中&#xff0c;slowlog&#xff08;慢日志&#xff09;是用来记录查询和索引操作的性能数据&#xff0c;帮助你诊断性能瓶颈。你可以为查询 (search slowlog) 和索引 (index slowlog) 配置慢日志。 数据准备 POST /products/_doc/1 {"product_name&quo…

CANape使用之新建工程

基本概念 CANape有两个基本概念&#xff1a;“工程”和“配置”&#xff0c;控制着CANape中进行的所有工作。 “工程”是指硬件设置&#xff0c;可能是连接到ECU或车辆总线上的Vector网络接口卡&#xff0c;或者连接到ECU或ADAS传感器(如雷达)上的高速ECU内存接口(VX1000)&am…

Spring Cloud Sleuth 分布式链路追踪入门

您好&#xff0c;我是今夜写代码,今天学习下分布式链路组件Spring Cloud Sleuth。 本文内容 介绍了分布式链路的思想 Sleuth 和 Zipkin 简单集成Demo,并不涉及 Sleuth原理。 为什么要用链路追踪&#xff1f; 微服务架构下&#xff0c;一个复杂的电商应用&#xff0c;完成下…

Chrome 132 版本开发者工具(DevTools)更新内容

Chrome 132 版本开发者工具&#xff08;DevTools&#xff09;更新内容 一、使用 Gemini 调试 Network、Source 和 Performance Chrome 131 可以使用 Gemini 调试 CSS&#xff0c;现在可以调试更多模块了 与元素面板中的右键菜单类似&#xff0c;要打开 AI 辅助面板并开始与 …

[白月黑羽]关于风机协议工具的解答

架构 python3.8pyqt5 先来看下原题&#xff1a; 视频中软件的效果 先来看下程序的效果如何&#xff0c;看上去大概相似 对应代码已经上传到了gitcode https://gitcode.com/m0_37662818/fan_protocol_tool/overview 实现中的难点是双悬浮可视化&#xff0c;同时要高亮悬浮对…

使用C#在目录层次结构中搜索文件以查找目标字符串

例程以递归方式搜索目录层次结构中的文件以查找目标字符串。它可以搜索几乎任何类型的文件&#xff0c;即使它不包含 Windows 理解的文本。例如&#xff0c;它可以搜索 DLL 和可执行文件以查看它们是否恰好包含字符串。 下面的代码中显示的ListFiles 方法完成了大部分工作。 …