Springboot全局异常处理

Springboot全局异常处理

  • 一、不使用全局异常处理器
  • 二、全局异常处理器
    • 1.自定义常量(返回状态码)
    • 2.手动抛出异常
    • 4.编写全局异常处理器
    • 3.测试结果
  • 三、全局异常处理方式二
    • 1.定义状态码常量
    • 2. 定义基础接口(面向接口编程)
    • 3.定义枚举类
    • 4.自定义数据传输对象
    • 5.定义全局异常处理器
    • 6.测试1
    • 7.测试2
  • 四、值得参考的博客


为什么使用全局异常?

  • 在开发过程中,不管是 Dao、Servie、Controller,层都有可能发生异常,对于异常处理,通常是 try-catch 或者直接 throw,这会让 try-catch 的代码在代码中任意出现,系统的代码耦合度高,代码不美观,统一异常处理可以美化代码。

如何使用全局异常?

  • 在后端处理请求过程中发生了异常,DispatcherServlet 将异常处理委托给异常处理器(处理异常的类)。实现 HandlerExceptionResolver 接口的都是异常处理类。
  • 项目的异常一般集中处理,定义全局异常处理器。再结合框架提供的注解,诸如:@ExceptionHandler@ControllerAdvice@RestControllerAdvice 一起完成异常的处理。注意: 一定要和Controller中的注解(@Controller 和 RestController)保持一致性。
  • @ControllerAdvice@RestControllerAdvice 区别在于:@RestControllerAdvice 加了@RepsonseBody

一、不使用全局异常处理器

  • ① 编写控制器相关的代码,模拟出现了空指针异常。NullPointerException

    @RestController
    public class Controller {
    
        @GetMapping("/divide")
        public String divide(){
            String str = null;
            str.toString();
            return "success";
        }
    }
    
  • ② 发送请求返回结果查看。
    在这里插入图片描述


二、全局异常处理器

  • SpringBoot中,@ControllerAdvice 或 @RestControllerAdvice 即可开启全局异常处理,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用@ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。

1.自定义常量(返回状态码)

/**
 * 返回状态码的常量
 **/
public class StatusCodeConstant {
    public static final Integer ERROR = 500; //服务器非法错误
}

2.手动抛出异常

@RestController
public class Controller {
    @GetMapping("/divide")
    public String divide(){
        String str = null;
        str.toString();
        return "success";
    }
}

4.编写全局异常处理器

    /**
     * 处理空指针的异常
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public String exceptionHandler(NullPointerException e){
        return "<h1>服务器出现错误,请联系管理员 ====> " + e.getMessage() + "</h1>";
    }

3.测试结果

在这里插入图片描述

  • 建议在参数签名中尽可能具体异常类,以减少异常类型和原因异常之间不匹配的问题,考虑创建多个@ExceptionHandler 方法的,每个方法通过其签名匹配单个特定的异常类型。最后增加一个根异常,考虑没有匹配的其他情况。

三、全局异常处理方式二

1.定义状态码常量

public class StatusCodeConstant {
    public static final Integer SUCCESS = 200;  //返回状态正常
    public static final Integer ERROR = 0; //返回错误
}

2. 定义基础接口(面向接口编程)

/**
 * 响应信息的基础接口
 **/
public interface ResponseResultBaseInfo {
    /**
     *  错误码
     */
    Integer getResultCode();

    /**
     * 错误描述
     */
    String getResultMsg();
}

3.定义枚举类

/**
 * 异常处理枚举类
 */
public enum ResponseEnum implements ResponseResultBaseInfo{

    // 数据操作错误定义
    SUCCESS(200, "success"),
    ERROR(500,"error");

    /**
     * 错误码
     */
    private final Integer resultCode;

    /**
     * 错误描述
     */
    private final String resultMsg;

    ResponseEnum(Integer resultCode, String resultMsg) {
        this.resultCode = resultCode;
        this.resultMsg = resultMsg;
    }

    @Override
    public Integer getResultCode() {
        return resultCode;
    }

    @Override
    public String getResultMsg() {
        return resultMsg;
    }
}

4.自定义数据传输对象

/**
 * 自定义数据传输对象
 */
@Data
public class ResponseResult {
    /**
     * 响应代码
     */
    private Integer code;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应结果
     */
    private Object result;
    public ResponseResult(){

    }

    public ResponseResult(ResponseResultBaseInfo res) {
        this.code = res.getResultCode();
        this.message = res.getResultMsg();
    }

    /**
     * 成功
     */
    public static ResponseResult success() {
        return success(null);
    }

    /**
     * 成功
     */
    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(ResponseEnum.SUCCESS.getResultCode());
        responseResult.setMessage(ResponseEnum.SUCCESS.getResultMsg());
        responseResult.setResult(data);
        return responseResult;
    }

    /**
     * 失败
     */
    public static ResponseResult error(ResponseResultBaseInfo res) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(res.getResultCode());
        responseResult.setMessage(res.getResultMsg());
        responseResult.setResult(null);
        return responseResult;
    }

    /**
     * 失败
     */
    public static ResponseResult error(Integer code, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(code);
        responseResult.setMessage(message);
        responseResult.setResult(null);
        return responseResult;
    }

    /**
     * 失败
     */
    public static ResponseResult error(String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(StatusCodeConstant.ERROR);
        responseResult.setMessage(message);
        responseResult.setResult(null);
        return responseResult;
    }

}

5.定义全局异常处理器

/**
 * 全局异常处理器
 **/
@RestControllerAdvice 
public class ExceptionHandlerConfig {
    @ExceptionHandler(NullPointerException.class)
    public ResponseResult nullPointException(NullPointerException e) {
        return ResponseResult.error(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseResult exception() {
        return ResponseResult.error(ResponseEnum.ERROR);
    }
}

6.测试1

    @GetMapping("/latest")
    public ResponseResult getSensorDataLatest() {
        return ResponseResult.success("数据传输成功");
    }

在这里插入图片描述

7.测试2

    @GetMapping("/latest")
    public ResponseResult getSensorDataLatest() {
        int a = 1;
        if(a == 1)
            throw new ArithmeticException();
        return ResponseResult.success("数据传输成功");
    }

在这里插入图片描述


四、值得参考的博客

  • Spring Boot项目优雅的全局异常处理方式(全网最新)
  • Spring的@ExceptionHandler注解使用方法
  • SpringBoot全局异常处理(优缺点)以及统一返回对象、错误码按业务模块设计示例,序列化后与数据库数据时间差8小时

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

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

相关文章

Linux安装vLLM模型推理框架问题总汇

简介 vLLM 是一个专为大规模语言模型&#xff08;Large Language Models, LLM&#xff09;推理优化的服务框架和推理引擎。它可以高效地管理和部署预先训练好的大型语言模型&#xff0c;尤其是那些具有极高参数数量和复杂度的模型&#xff0c;如GPT系列及其他基于Transformer架…

字符分类函数(iscntrl、i是space.....)---c语言

目录 一、定义二、字符分类函数2.1 -iscntrl&#xff08;&#xff09;2.1.1定义2.1.2使用举例 2.2 -isspace&#xff08;&#xff09;2.2.1描述2.2.2使用举例 2.3-isdigit()2.3.1描述2.3.2使用举例 2.4-isxdigit()2.4.1描述 2.5-islower()2.5.1描述2.5.2使用举例 2.6-isupper()…

VXLAN学习笔记

声明&#xff1a;该博客内容大部分参考参考链接整理 什么是VXLAN&#xff1f; VXLAN(Virtual Extensible LAN)即虚拟扩展局域网&#xff0c;是大二层网络中广泛使用的网络虚拟化技术。在源网络设备与目的网络设备之间建立一条逻辑VXLAN隧道&#xff0c;采用MAC in UDP的封装方…

【开源】SpringBoot框架开发房屋出售出租系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 房屋销售模块2.2 房屋出租模块2.3 预定意向模块2.4 交易订单模块 三、系统展示四、核心代码4.1 查询房屋求租单4.2 查询卖家的房屋求购单4.3 出租意向预定4.4 出租单支付4.5 查询买家房屋销售交易单 五、免责说明 一、摘…

MySQL语法分类 DQL(5)分组查询

为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),math int,english int );insert into student (id,name,age,sex,address,math,english) values (1,马云,55,男,杭州,66,78),…

YOLOV5 模型:利用tensorboard查看网络结构和yaml文件介绍

1、前言 yolov5目录中,关于模型构建的为下面的部分: *.yaml 文件,具体的配置参数common文件,具体模块的搭建,neck的spp等等yolo文件,搭建yolo的代码这部分为了后续添加改进模块,所以详细介绍下 2、yaml 文件 因为之前实战的模型都是v5s,这里我们打开yolov5s.yaml文件…

[Windows] Win11 常用快捷键

文章目录 &#x1f680; [Windows] Win11 常用快捷键&#x1f310; Windows 操作系统&#x1f525; Windows 11 &#x1f310; Windows 11 快捷键概览&#x1f525; 基本快捷键&#x1f525; 窗口快捷键&#x1f525; 功能快捷键 &#x1f4dd; 小结 &#x1f680; [Windows] W…

RPC通信原理(一)

RPC通信原理 RPC的概念 如果现在我有一个电商项目&#xff0c;用户要查询订单&#xff0c;自然而然是通过Service接口来调用订单的实现类。 我们把用户模块和订单模块都放在一起&#xff0c;打包成一个war包&#xff0c;然后再tomcat上运行&#xff0c;tomcat占有一个进程&am…

ResNet学习笔记

一、residual结构 优点&#xff1a; &#xff08;1&#xff09;超深的网络结构(突破1000层) &#xff08;2&#xff09;提出residual模块 &#xff08;3&#xff09;使用Batch Normalization加速训练(丢弃dropout) 解决问题&#xff1a; &#xff08;1&#xff09; 梯度消失和…

高效采购:最大化利用电子元器件采购商城

实现高效采购需要最大化利用电子元器件采购商城的各项功能和资源。以下是一些方法和策略&#xff1a; 充分利用搜索和筛选功能&#xff1a; 采购商城通常提供强大的搜索和筛选功能&#xff0c;包括关键词搜索、参数筛选、品牌筛选等。通过充分利用这些功能&#xff0c;可以快速…

Linux中udp服务端,客户端的开发

UDP通信相关函数&#xff1a; ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 函数说明&#xff1a;接收信息 参数说明&#xff1a;sockfd:套接字buf:要接收的缓冲区len:缓冲区…

人形机器人进展:IEEE Robotics出版双臂通用协同机械手操作架构

文章目录 1. Main2. My ThoughtsReference彩蛋a. OpenAI 投资: 人形机器人公司 Figure AIb. 人工智能软件工程师 Devin 上线 1. Main 图1 人居环境下的人形双臂机器人系统 通用人形机器人 作为近年来机器人与AI交叉领域的研究热点和技术竞争高地&#xff0c;因其具备在 非结构化…

python二级备考(3)-综合应用

1 《命运》是著名科幻作家倪匡的作品。这里给出《命运》的一个网络版本文件&#xff0c;文件名为“命运. txt”。 问题1 (5分) :在PY301-1. py文件中修改代码&#xff0c;对“命运. txt”文件进行字符频次统计&#xff0c;输出频次最高的中文字符(不包含标点符号)及其频次&…

【C++补充1】map容器

1.单映射 1.单映射&#xff0c;first:键 second:值 2.键唯一&#xff0c;如果重复&#xff0c;相同键插入 会覆盖值。 使用方法&#xff1a;pair<int, string> data(1, "Iloveyou"); 1.main int main() {//单映射//first:键 second:值//键唯一&am…

如何选择适合自己的编程语言?

如何选择适合自己的编程语言&#xff1f; 《探索编程语言&#xff1a;如何选择适合自己的编程语言&#xff1f;》摘要引言如何选择适合自己的编程语言&#xff1f;1. 了解不同的编程范式2. 考虑所需的工作领域3. 考虑生态系统和社区支持4. 考虑学习曲线和语法简洁性 总结参考资…

JVM虚拟机:通过jconsole远程连接解决JVM报错

本文重点 前面我们介绍过的一些工具都是使用命令行的方式来帮助我们完成&#xff0c;本文我们将使用一种图形化界面的方式来远程连接&#xff0c;然后完成关于JVM的检测任务。 jconsole jconsole是一个JVM的检测工具&#xff0c;这个工具任何安装了Java的电脑上都有的&#…

学生时期学习资源同步-1 第一学期结业考试题8

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载

CSS学习(1)-选择器

一、基本选择器 1. 通配选择器 作用&#xff1a;可以选中所有的 HTML 元素。 语法&#xff1a; * { 属性名: 属性值; }举例&#xff1a; /* 选中所有元素 */ * { color: orange; font-size: 40px; }主要用于&#xff1a;清除样式。 2. 元素选择器 作用&#xff1a;为页面…

MySQL语法分类 DQL(3)排序查询

为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),math int,english int );insert into student (id,name,age,sex,address,math,english) values (1,马云,55,男,杭州,66,78),…

Linux中 vim 编辑器的使用

文章目录 前言一、vim编辑器模式二、简单的插入、保存和退出三、 命令模式下常用命令即其作用1. 命令模式 思维导图 前言 首先&#xff0c;了解一下 什么是vim 编辑器&#xff1f;在不同的系统中&#xff0c;文本的管理也会不同&#xff1b;windos系统就不多说了&#xff0c…