Spring Boot实现统一异常处理的技术解析

news2024/11/18 6:20:16

引言

在软件开发过程中,异常处理是非常重要的一环。一个好的异常处理机制可以帮助我们更好地定位问题,提高代码的可维护性和稳定性。Spring Boot作为一款轻量级的Java开发框架,提供了一种简单而高效的方式来实现统一异常处理。本文将详细介绍如何使用Spring Boot实现统一异常处理。

了解异常处理的基本概念

在Java中,异常是程序运行过程中出现的问题,可以分为两大类:受检异常(Checked Exception)和非受检异常(Unchecked Exception)。受检异常需要程序员显式地进行处理,而非受检异常则不需要。为了提高代码的可读性和可维护性,我们通常会对异常进行统一的处理。

Spring Boot中的统一异常处理

Spring Boot提供了一个全局的异常处理器(GlobalExceptionHandler),可以捕获所有的异常,并进行统一的处理。要实现统一异常处理。

创建全局统一异常处理类

创建一个自定义的异常处理类,实现ControllerAdvice@RestControllerAdvice注解。这个类将会成为全局的异常处理器。

@ControllerAdvice(basePackages="com.example.controller")
public class GlobalExceptionHandler {
    @ExceptionHandler(value = {Exception.class})
    @ResponseBody
    public <T> Resp<T> exceptionHandler(Exception e){
        //这里先判断拦截到的Exception是不是我们自定义的异常类型
        if(e instanceof CustomException){
            CustomException customException = (CustomException)e;
            return Resp.error(customException.getCode(),customException.getMsg());
        }

        //如果拦截的异常不是我们自定义的异常(例如:数据库主键冲突)
        return Resp.error(500,"服务器端异常");
    }
}
创建自定义的异常类

首先,我们需要定义一些自定义的异常类,以便更好地区分各种异常情况。例如:

public class CustomException extends RuntimeException {

    private int code = 500;
    private String msg = "服务器异常";


    public CustomException(CustomExceptionCodeMsg customExceptionCodeMsg) {
        super();
        this.code = customExceptionCodeMsg.getCode();
        this.msg = customExceptionCodeMsg.getMsg();

    }

    public CustomException(int code, String msg) {
        super();
        this.code = code;
        this.msg = msg;

    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

}
创建统一信息返回类
public class Resp<T> {

    //服务端返回的错误码
    private int code = 200;
    //服务端返回的错误信息
    private String msg = "success";
    //我们服务端返回的数据
    private T data;

    private Resp(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> Resp success(T data) {
        Resp resp = new Resp(200, "success", data);
        return resp;
    }

    public static <T> Resp success(String msg, T data) {
        Resp resp = new Resp(200, msg, data);
        return resp;
    }

    public static <T> Resp error(CustomExceptionCodeMsg customExceptionCodeMsg) {
        Resp resp = new Resp(customExceptionCodeMsg.getCode(), customExceptionCodeMsg.getMsg(), null);
        return resp;
    }

    public static <T> Resp error(int code, String msg) {
        Resp resp = new Resp(code, msg, null);
        return resp;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

}
创建一个枚举类型
public enum CustomExceptionCodeMsg {
    INVALID_CODE(0000, "验证码无效"),
    USERNAME_NOT_EXISTS(11111, "用户名不存在");

    private int code;
    private String msg;

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }


    CustomExceptionCodeMsg(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

}
创建一个controller
@RestController
public class ExceptionController {
    @GetMapping("/exception")
    public Resp<String> exception(String name) {

        if ("ok".equals(name)) {
            return Resp.success("成功");
        }
        if ("err".equals(name)) {
            //抛业务相关的异常
            throw new CustomException(CustomExceptionCodeMsg.USERNAME_NOT_EXISTS);
        }

        if ("errcode".equals(name)) {
            throw new CustomException(CustomExceptionCodeMsg.INVALID_CODE);
        }
        if ("0".equals(name)) {
            int i = 1 / 0;
        }

        return Resp.success(name);
    }

    @GetMapping("/list")
    public Resp<List> list() {
        List<String> list = Arrays.asList("CSDN", "奇遇少年");

        return Resp.success(list);
    }
}

运行测试:

使用全局异常处理器的优势:

(1)提高代码的可读性和可维护性。通过将异常处理逻辑集中在一个地方,可以降低代码的复杂度,提高代码的可读性。同时,当需要修改异常处理逻辑时,只需要修改一个地方即可。

(2)提高系统的稳定性。通过全局的异常处理器,我们可以更好地定位和处理异常,避免因为未处理的异常导致系统崩溃。

(3)方便进行日志记录和监控。全局的异常处理器可以方便地记录异常信息,便于开发人员进行调试和排查问题。同时,也可以方便地将异常信息发送到监控系统,进行实时的监控和报警。

结语

通过本文的介绍,你已经学会了如何在Spring Boot中实现统一异常处理。通过定义自定义异常和创建全局异常处理器,我们能够更好地管理和处理应用中的各种异常情况。这不仅提高了代码的可读性和可维护性,还能够为用户提供更友好的错误信息。合理使用自定义异常,将有助于构建一个稳健的应用,为用户提供更加可靠的服务。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神器yakit之web fuzzer功能

前言 yakit并不像burp一样单独设置爆破模块&#xff0c;但是yakit也是可以爆破的&#xff0c;并且更好用&#xff08;个人感觉&#xff09;。 手工测试场景中需要渗透人员对报文进行反复的发送畸形或者特定的payload进行查看服务器的反馈并以此来进行下一步的判断。 Fuzz标签便…

动态规划:完全背包问题

本题力扣上没有&#xff0c;是刷的卡码网第52题52. 携带研究材料感兴趣的小伙伴可以去刷一下&#xff0c;是ACM模式。 题目&#xff1a; 题目描述&#xff1a; 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成果。他需要带…

x-cmd pkg | skate - 个人键值对存储工具

目录 简介用户首次快速实验指南功能特点竞品和相关作品进一步探索 简介 skate 是个人键值对存储工具&#xff0c;具备数据加密、云端数据备份以及多设备同步等功能。 它由 Charm 团队开发&#xff0c;借用 Charm Cloud 向用户提供一种快捷的方式来保存和检索各种数据&#xf…

接口测试 02 -- JMeter入门到实战

前言 JM eter毕竟是做压测的工具&#xff0c;自动化这块还是有缺陷。 如果公司做一些简单的接口自动化&#xff0c;可以考虑使用JMeter快速完成&#xff0c;如果想做完善的接口自动化体系&#xff0c;建议还是基于Python来做。 为什么学习接口测试要先从JMeter开始&#xff1f;…

VS Code + Python + Selenium 自动化测试基础-01

VS Code Python Selenium 自动化测试基础-01 让我们来讲一个故事为什么要写自动化开发前的准备工作牛刀小试开常用的web DriverAPI-定位元素id定位&#xff1a;find_element_by_id()name 定位&#xff1a;find_element_by_name()class 定位&#xff1a;find_element_by_class…

Oracle SQL Developer执行sql脚本文件

文件过于大&#xff0c;无法打开&#xff0c;直接在界面执行。 ①将文件放置到D盘&#xff0c;文件名 daochu5.sql ② 在工具执行SQL界面输入 d:\daochu5.sql;,点击运行按钮运行

范围运算between...and和空判断

目录 between...and 空判断 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 between...and between...and的主要功能是用户进行范围查询,语法如下: select 字段 | 数值 between 最小值 and 最大值; 1.查询工资在 1500 ~ 3000 的所…

基于JavaWeb+SSM+Vue基于微信小程序生鲜云订单零售系统的设计和实现

基于JavaWebSSMVue基于微信小程序生鲜云订单零售系统的设计和实现 滑到文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 滑到文末获取源码 Lun文目录 目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计…

逻辑运算

目录 AND OR NOT Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 逻辑运算可以保证连接多个条件&#xff0c;连接主要使用 AND、OR 、NOT完成 AND 1.查询职位不是办事员&#xff0c;但是工资低于 300 的员工信息 这个范例可以理…

【GitHub项目推荐--全球首个开源图像识别系统】【转载】

你知道人脸识别、商品识别、车辆识别&#xff0c;以图搜图乃至自动驾驶&#xff0c;背后的技术是什么嘛&#xff1f;并不是图像分类、目标检测这些东西&#xff0c;而是综合使用目标检测、图像分类、度量学习、图像检索的【通用图像识别系统】… 度量学习是啥&#xff1f;图像检…

Postman接口测试高阶——精通Mock Server模拟服务器的创建及使用等

文章目录 一、什么是Mock Server二、为什么使用Mock Server四、Mock Server使用场景五、创建Mock Server模拟服务器1.创建Mock Server2.配置Mock Server3.创建Mock Server模拟服务器成功 六、使用Mock Server模拟服务器七、修改Mock Server模拟服务器配置 一、什么是Mock Serve…

AI跟踪报道第25期-新加坡内哥谈技术-本周AI发展更新-酷炫来袭

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Java毕业设计-基于springboot的学习英语管理系统-第89期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于springbootvue的医院管理系统&#xff1a;前端 vue、bootstrap、coreui&#xff0c;后端 maven、springmvc、spring、mybatis、redis&#xff0c;角色分为管理员、医…

后台管理系统: sku管理模块

完成添加SKU静态组件 完成添加SKU静态组件 点击添加sku&#xff0c;触发回调&#xff0c;场景为2 静态界面完成 <template><div><el-form ref"form" label-width"80px"><el-form-item label"SPU名称"> 海绵宝宝 <…

用红黑树封装实现map与set

红黑树 红黑树 &#xff0c;是一种 二叉搜索树 &#xff0c;但 在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是 Red 或 Black 。 通过对 任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路 径会比其他路径长出俩倍 &#xff…

新品发布 | 多通道总线记录仪TLog1004,是你期待的吗?

新品发布 2024年1月12日&#xff0c;同星智能又发布一款多通道 CAN &#xff08;FD&#xff09;总线、LIN 总线接口logger设备&#xff0c;此款产品在TLog1002基础上进行了升级&#xff0c;同时内置 3 路数字输入和 2 路数字输出&#xff0c;便于多种信号测量和系统集成。可以满…

12- OpenCV:算子(Sobel和Laplance) 和Canny边缘检测 详解

目录 一、Sobel算子 1、卷积应用-图像边缘提取 2、Sobel算子&#xff08;索贝尔算子&#xff09; 3、相关的API&#xff08;代码例子&#xff09; 二、Laplance算子 1、理论 2、API使用&#xff08;代码例子&#xff09; 三、Canny边缘检测 1、Canny算法介绍 2、API使…

Vulnhub-LORD OF THE ROOT: 1.0.1

一、信息收集 端口扫描、发现只开了22端口 连接ssh后提示端口碰撞&#xff1a; 端口敲门是一种通过在一组预先指定的关闭端口上产生连接请求&#xff0c;从外部打开防火墙上的端口的方法。一旦收到正确地连接请求序列&#xff0c;防火墙规则就会被动态修改&#xff0c;以允许…

eNSP学习——配置通过Telnet登陆系统

实验内容&#xff1a; 模拟公司网络场景。R1是机房的设备&#xff0c;办公区与机房不在同一楼层&#xff0c;R2和R3模拟员工主机&#xff0c; 通过交换机S1与R1相连。 为了方便用户的管理&#xff0c;需要在R1上配置Telnet使员工可以在办公区远程管理机房设备。 为…

探究Java中的链表

引言&#xff1a; 在Java编程中&#xff0c;链表是一种常见的数据结构&#xff0c;具有灵活的内存管理和动态的元素插入与删除能力。本篇博客将深入探讨链表的结构和概念&#xff0c;比较链表与顺序表的区别&#xff0c;介绍Java中LinkedList的常用函数并通过示例说明LinkedLis…