【实战案例】SpringBoot项目中异常处理通用解决方案

news2024/10/19 18:35:18

项目中经常会出现一些异常,比如在新增项目的时候必要的字段没有填写。在springboot项目中,遇到异常会往上抛出给调用方,DAO层遇到异常抛给Service层,Service层遇到异常抛给Controller层,Controller层遇到异常就抛给了SpringMVC框架。对于前端来说是无法感知的,并不知道具体发生了什么错误。如果使用try-catch的话代码又过于冗余,所以需要把异常处理的逻辑统一进行管理。
在这里插入图片描述
上图是设想的解决方案,通过SpringMVC提供的控制器增强类统一由一个类完成异常的捕获,背后是AOP机制。

实现过程:
枚举类CommonError用于定义常见的错误类型

package com.gavin.base.exception;

/**
 * @author Gavin
 * @description 通用错误信息
 * @date 2024/10/15
 **/
public enum CommonError {

    UNKOWN_ERROR("执行过程异常,请重试。"),
    PARAMS_ERROR("非法参数"),
    OBJECT_NULL("对象为空"),
    QUERY_NULL("查询结果为空"),
    REQUEST_NULL("请求参数为空");

    private String errMessage;

    public String getErrMessage() {
        return errMessage;
    }

    private CommonError( String errMessage) {
        this.errMessage = errMessage;
    }
}

自定义异常类EffecttiveStudyException用来封装项目中特定异常信息

package com.gavin.base.exception;

/**
 * @author Gavin
 * @description 自定义高效学习在线类项目异常类
 * @date 2024/10/15
 **/
public class EffectiveStudyException extends RuntimeException{
    private String errMessage;

    public EffectiveStudyException() {
        super();
    }

    public EffectiveStudyException(String errMessage) {
        super(errMessage);
        this.errMessage = errMessage;
    }

    public String getErrMessage() {
        return errMessage;
    }

    public static void cast(CommonError commonError){
        throw new EffectiveStudyException(commonError.getErrMessage());
    }
    public static void cast(String errMessage){
        throw new EffectiveStudyException(errMessage);
    }
}

错误响应类RestErrorResponse用于统一封装并返回给前端的错误信息

package com.gavin.base.exception;

import java.io.Serializable;

/**
 * @author Gavin
 * @description 和前端约定返回的异常信息
 * @date 2024/10/15
 **/
public class RestErrorResponse implements Serializable {

    private String errMessage;

    public RestErrorResponse(String errMessage){
        this.errMessage= errMessage;
    }

    public String getErrMessage() {
        return errMessage;
    }

    public void setErrMessage(String errMessage) {
        this.errMessage = errMessage;
    }
}

定义全局异常处理器GlobalExceptionHandler类,这个类可以认为就是AOP机制中的一个切面,在系统各种专门处理所有控制器方法抛出的异常。以下是两个比较重要的注解:
@ControllerAdvice:用来标识一个全局异常处理类,所有被@Controller注解的控制器中的异常都会被它捕获。
@ExceptionHandler:用于捕获特定类型的异常。在这里,EffectiveStudyException 和其他普通异常都分别有处理方法。

package com.gavin.base.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * @author Gavin
 * @description 全局异常处理器
 * @date 2024/10/15
 **/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(EffectiveStudyException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse customException(EffectiveStudyException e) {
        log.error("【系统异常】{}",e.getErrMessage(),e);
        return new RestErrorResponse(e.getErrMessage());

    }

    @ResponseBody
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse exception(Exception e) {

        log.error("【系统异常】{}",e.getMessage(),e);

        return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
    }
}

通过上述全局异常处理器,任何抛出的EffectiveStudyException或未被预期的异常都会被这个类统一处理,并返回一个标准的错误信息。

上述自定义后,对于抛出异常的地方可以进行替换,例如

throw new RuntimeException("课程的价格不能为空且必须大于0");

可以替换为

throw new EffectiveStudyException("课程的价格不能为空且必须大于0");
或者
EffectiveStudyException.cast("课程的价格不能为空且必须大于0");

两种形式是等价的,但后者更为简洁。如果捕获了上述异常,前端返回的就是对应内容的json数据信息,如下:
在这里插入图片描述

当存在其他异常时,如controller中存在一个除数为0的情形,如果在Controller中没有进行显示的try-catch捕获,异常会被直接抛出,由SpringMVC框架捕获并向上传递,SpringMVC会将这个异常传递给全局异常处理器类(GlobalExceptionHandler类),由于不是EffectiveStudyException类型的错误,所以交由兜底Exception处理,返回了UNKOWN_ERROR对应的错误信息(这里对于常见错误可定义特定信息返回)。如下:
在这里插入图片描述

这里可能会存在疑问,为什么不直接返回e.getMessage()的具体信息而是笼统的执行过程异常请重试?考虑的因素有:异常具体信息中可能包含敏感的系统内部信息,如数据库查询语句,服务器路径及框架细节等信息,有风险。另外,复杂的信息用户体验不好,提示信息应该简洁友好。但实际中开发环境有时候是有必要放出具体异常信息的,生产环境不适合放具体异常信息。

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

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

相关文章

Qt-系统网络HTTP客户端(66)

目录 描述 相关函数 使用 准备工作 处理响应 测试 代码 补充 描述 进⾏ Qt 开发时, 和服务器之间的通信很多时候也会⽤到 HTTP 协议 Qt 中提供了客户端,但是并没有提供相应的服务器的库,所以这里我们只讨论 客户端 • 通过 HTTP 从服务器获取…

Unity 2d UI 实时跟随场景3d物体

2d UI 实时跟随场景3d物体位置&#xff0c;显示 3d 物体头顶信息&#xff0c;看起来像是场景中的3dUI&#xff0c;实质是2d UIusing System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; /// <summary>…

RequestBody接收参数报错com.fasterxml.jackson.databind.exc.MismatchedInputException

目录&#xff1a; 1、错误现象2、解决办法3、最终验证 1、错误现象 报错的现象和代码如下&#xff1a; 2、解决办法 查了很多都说参数类型对不上&#xff0c;但是明明是对上的&#xff0c;没有问题&#xff0c;最后只有换接收方式后验证是可以的&#xff1b;最终想了一下&…

Flink状态一致性保证

前言 一个Flink作业由一系列算子构成&#xff0c;每个算子可以有多个并行实例&#xff0c;这些实例被称为 subTask&#xff0c;每个subTask运行在不同的进程或物理机上&#xff0c;以实现作业的并行处理。在这个复杂的分布式场景中&#xff0c;任何一个节点故障都有可能导致 F…

智能算力中心万卡GPU集群架构深度解析

智能算力中心万卡GPU集群架构深度分析 自ChatGPT发布&#xff0c;科技界大模型竞赛如火如荼。数据成新生产要素&#xff0c;算力成新基础能源&#xff0c;大模型成新生产工具&#xff0c;“AI”转型势不可挡。模型参数量突破万亿&#xff0c;对算力需求升级&#xff0c;超万卡…

Docker学习笔记(2)- Docker的安装

1. Docker的基本组成 镜像&#xff08;image&#xff09;&#xff1a;Docker镜像就像是一个模板&#xff0c;可以通过这个模板来创建容器服务。通过一个镜像可以创建多个容器。最终服务运行或者项目运行就是在容器中。容器&#xff08;container&#xff09;&#xff1a;Docker…

Ansible概述

目录 一、ansible简介 二、absible的特点 三、ansible的工作原理以及流程 四、ansible环境安装部署 五、ansible命令行模块 六、inventory 主机清单 一、ansible简介 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。…

MT1341-MT1350 码题集 (c 语言详解)

MT1341反比例函数 c 语言实现代码 #include <stdio.h>double f(double x) { return 1.0 / x; }double trapezoidal_integration(double a, double b, int n) {// computer step lengthdouble h (b - a) / n;// computer points valuedouble sum (f(a) f(b)) / 2.0;//…

初阶数据结构【2】--顺序表(详细且通俗易懂,不看一下吗?)

本章概述 线性表顺序表顺序表问题与思考彩蛋时刻&#xff01;&#xff01;&#xff01; 线性表 概念&#xff1a;一些在逻辑上成线性关系的数据结构的集合。线性表在逻辑上一定成线性结构&#xff0c;在物理层面上不一定成线性结构。常见的线性表&#xff1a;顺序表&#xff0…

Origin画图——百分比堆积柱状图(深度学习篇)

1.当数据有以下特征&#xff0c;不同特征在不同情况下的数值的时候就可以使用百分比柱状图表示。 1 2.将自己的数据导入到Origin中&#xff0c;本示例中以不同机器学习的方法的在不同测试集下的R2作为示例。数据如下所示。绘图百分比柱状图&#xff0c;两种都可以。 3.生成的…

推荐一个可以免费上传PDF产品图册的网站

​在数字化时代&#xff0c;企业将产品图册以PDF格式上传至网络&#xff0c;不仅便于客户浏览和下载&#xff0c;还能提升企业的专业形象。今天&#xff0c;就为您推荐一个可以免费上传PDF产品图册的网站——FLBOOK&#xff0c;轻松实现产品图册的在线展示。 1.注册登录&#x…

【xilinx-versal】【Petalinux】添加TMP75温度传感器Linux驱动

Xilinx versal添加TMP75温度传感器Linux驱动 I2C总线的内核配置打开Cadence I2C 控制器配置xilinx I2C配置(不使用)添加设备树总结I2C总线的内核配置 TMP75挂载第一个i2c总线上,地址是0x48。 petalinux-config -c kernel打开内核配置界面。 打开Cadence I2C 控制器配置 │…

Linux——用户/用户组

创建用户组groupadd groupadd 用户组 删除用户组groupdel groupdel 用户组 创建用户useradd useradd 用户名 - g 用户组 useradd 用户名 -d HOME路径 删除用户userdel userdel 用户 userdel -r 用户 &#xff08;删除用户的 HOME 目录&#xff0c;不使用 -r &#xff0…

FlinkCDC 实现 MySQL 数据变更实时同步

文章目录 1、基本介绍2、代码实战2.1、数据源准备2.2、代码实战2.3、数据格式 1、基本介绍 Flink CDC 是 Apache Flink 提供的一个功能强大的组件&#xff0c;用于实时捕获和处理数据库中的数据变更。可以实时地从各种数据库&#xff08;如MySQL、PostgreSQL、Oracle、MongoDB…

结构体通讲——数据结构解惑

文章目录 一.第一种写法二.第二种三.第三种四.-> 结构&#xff1a;一个变量里包含很多变量 一.第一种写法 int a[]&#xff1b;//一个数组中可以包含许多相同类型的数组 想让一个数组中包含很多不同类型的变量用结构 struct {int a;char bc; }t,ti;//t和ti拥有了前面所定…

谷歌审核放宽,恶意软件不再封号?是反垄断案影响还是开发者们的错觉

最近&#xff0c;谷歌因其“垄断”案而成为科技行业的焦点&#xff0c;这个案件可能导致谷歌业务的重大调整。同时&#xff0c;在Google Play上&#xff0c;一些开发者发现谷歌审核好像放宽了不少&#xff0c;这是不是与反垄断有关&#xff0c;谷歌应用上架或将迎来春天&#x…

MySQL-12.DQL-条件查询

一.DQL-条件查询 -- DQL:条件查询 -- 1.查询 姓名 为 杨逍 的员工 select id, username, password, name, gender, image, job, entrydate, create_time, update_timefrom tb_emp where name 杨逍;-- 2.查询 id小于等于5 的员工信息 select * from tb_emp where id < 5;-…

HT3382 2x75W D类立体声音频功放

1、特点 输出功率(BTL) 2x60W (VDD24V,RL4Ω,THDN1%) 2x75W(VDD24V,RL4Ω,THDN10%) 输出功率(PBTL) 115W(VDD24V,RL2Ω,THDN1%) 140W(VDD24V,RL2Ω,THDN10%) 单电源系统&#xff0c;4.5V-26V宽电压输入范围 超过93%效率&#xff0c;需散热器 扩频功能 MUTE功能 模拟差分/单端输…

LLM - 使用 Neo4j 可视化 GraphRAG 构建的 知识图谱(KG) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142938982 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Neo4j …

中科大科大讯飞开源OpenMusic:音乐生成更高质量,更有乐感

文章链接&#xff1a;https://arxiv.org/pdf/2405.15863 代码链接&#xff1a;https://github.com/ivcylc/qa-mdt Huggingface链接&#xff1a;https://huggingface.co/spaces/jadechoghari/OpenMusic Demo链接&#xff1a;https://qa-mdt.github.io/ &#xff08;chatgpt * 3…