SpringBoot全局异常处理

2023-10-30

需求

程序运行中可能出现各种错误,如果不对错误进行处理,那么客户端的体验会非常不好;但如果在业务代码中进行了太多的错误处理,造成代码臃肿,后期维护困难。因此,有必要进行全局的异常捕获,统一处理异常状况。

工具类

HTTP状态码工具类

package com.robot.robotservice.common;

/**
 * 返回状态码
 * 
 */
public class HttpStatus
{
    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功,但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;
}

统一返回格式

package com.robot.robotservice.common;

import java.util.HashMap;

/**
 * 统一返回格式
 * 
 */
public class AjaxResult extends HashMap<String, Object>
{
    private static final long serialVersionUID = 1L;

    /** 状态码 */
    public static final String CODE_TAG = "code";

    /** 返回内容 */
    public static final String MSG_TAG = "msg";

    /** 数据对象 */
    public static final String DATA_TAG = "data";

    /**
     * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
     */
    public AjaxResult()
    {
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     * 
     * @param code 状态码
     * @param msg 返回内容
     */
    public AjaxResult(int code, String msg)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     * 
     * @param code 状态码
     * @param msg 返回内容
     * @param data 数据对象
     */
    public AjaxResult(int code, String msg, Object data)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        if (StringUtils.isNotNull(data))
        {
            super.put(DATA_TAG, data);
        }
    }

    /**
     * 返回成功消息
     * 
     * @return 成功消息
     */
    public static AjaxResult success()
    {
        return AjaxResult.success("操作成功");
    }

    /**
     * 返回成功数据
     * 
     * @return 成功消息
     */
    public static AjaxResult success(Object data)
    {
        return AjaxResult.success("操作成功", data);
    }

    /**
     * 返回成功消息
     * 
     * @param msg 返回内容
     * @return 成功消息
     */
    public static AjaxResult success(String msg)
    {
        return AjaxResult.success(msg, null);
    }

    /**
     * 返回成功消息
     * 
     * @param msg 返回内容
     * @param data 数据对象
     * @return 成功消息
     */
    public static AjaxResult success(String msg, Object data)
    {
        return new AjaxResult(HttpStatus.SUCCESS, msg, data);
    }

    /**
     * 返回错误消息
     * 
     * @return
     */
    public static AjaxResult error()
    {
        return AjaxResult.error("操作失败");
    }

    /**
     * 返回错误消息
     * 
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult error(String msg)
    {
        return AjaxResult.error(msg, null);
    }

    /**
     * 返回错误消息
     * 
     * @param msg 返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static AjaxResult error(String msg, Object data)
    {
        return new AjaxResult(HttpStatus.ERROR, msg, data);
    }

    /**
     * 返回错误消息
     * 
     * @param code 状态码
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult error(int code, String msg)
    {
        return new AjaxResult(code, msg, null);
    }

    /**
     * 方便链式调用
     *
     * @param key 键
     * @param value 值
     * @return 数据对象
     */
    @Override
    public AjaxResult put(String key, Object value)
    {
        super.put(key, value);
        return this;
    }
}

配置全局异常处理类

全局异常处理作用在Controller层,业务代码的错误可以统一抛出给上层。

我们在处理不同错误时,用日志记录发生错误的接口,同时给前端返回相应的状态码和错误信息。

package com.robot.robotservice.exception;

import com.robot.robotservice.common.AjaxResult;
import com.robot.robotservice.common.HttpStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.nio.file.AccessDeniedException;

/**
 * 全局异常处理器
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 权限校验异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
    }
    
    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                          HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return AjaxResult.error(e.getMessage());
    }
    
    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }
    
    /**
     * 除0异常
     */
    @ExceptionHandler(ArithmeticException.class)
    public AjaxResult handleException(ArithmeticException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',除数不可为0.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }
    
    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }
}

测试

在Controller中定义一个测试方法,这里直接进行一个错误的运算(已经配置了对应的异常类处理方法)。

@GetMapping("/test")
public AjaxResult test() {
    int a = 1 / 0;
    return null;
}

前端接收值:

{
	"msg": "/ by zero",
	"code": 500
}

后端日志记录:

2023-04-27 10:04:36.396 ERROR 27944 --- [nio-8100-exec-4] c.r.r.exception.GlobalExceptionHandler   : 请求地址'/socket/test',除数不可为0.

java.lang.ArithmeticException: / by zero
...

可以看到成功捕获并处理了异常。

参考

https://gitee.com/y_project/RuoYi-Vue

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot全局异常处理 的相关文章

随机推荐

  • Python模块Collection——OrderedDict

    OrderedDict 有序字典 OrderedDict是dict的子类 它记住了内容添加的顺序 import collections print Regular dictionary d d a A d b B d c C for k v
  • 用Python实现双目立体匹配SAD算法

    SAD Sum of absolute differences 是一种图像匹配算法 SAD算法的基本流程 1 构造一个小窗口 类似与卷积核 2 用窗口覆盖左边的图像 选择出窗口覆盖区域内的所有像素点 3 同样用窗口覆盖右边的图像并选择出覆盖
  • 基于Matlab的时间序列(Time Series)(附代码)

    时间序列 一 模型介绍 1 1 时间序列的不同分类 1 2 时间序列构成要素 1 3 三种时间序列模型 1 3 1 AR p 模型 1 3 2 MA q 模型 1 3 3 ARMA p q 模型 1 3 4 ARIMA p d q 模型 1
  • Picture 【HDU - 1828】【对于扫描线更新的一些特殊情况】

    题目链接 这个问题 在以前写过博客 但是今朝再来看 属实还存有一些问题未曾解决 举个例子 我们来画一张图 并且给每个边标个序号 如图 我们有4条边 按照之前想的办法 我们进行处理 我们先放进去1这号边 再放入2这号边 实际上 这时候我们已经
  • JAVA使用Jedis操作Redis的基本常用的API。

    package com coderman test import com coderman entities Customer import com coderman entities Department import org junit
  • crafting interpreters 介绍

    crafting interpreters 作者 的博客 crafting interpreters 出生的介绍 英文 crafting interpreters 出生的介绍 中文 crafting interpreters 在线阅读 cr
  • Qt的快捷键汇总

    t的基础知识 感谢大家来看我的分享 一般操作的键盘快捷键 调试相关操作的键盘快捷键 项目相关操作的键盘快捷键 帮助相关操作的键盘快捷键 感谢大家来看我的分享 第一次分享 介绍一下Qt的快捷键 方便大家在工作中速查 一般操作的键盘快捷键 操作
  • 搞懂电路的极点和零点

    在这里 作者将尝试找出关于极点和零点的物理感觉 使用运算放大器来控制它们在复平面中的位置 并利用电路的自然响应来说明极点 零点位置的影响 单端口电路的自然响应 我们来看图1中的无源线性单端口电路 它包括电阻 电容和电感 图1 a 无源单端口
  • touchmove 长按_移动端 javascript 实现长按拖动

    最近我要在移动端实现一个长按拖动功能 发现一个库 https github com bevacqua d 非常好用 用起来也非常简单 下面是一个可以运行的例子 Document box1 height 200px background co
  • 项目 和 api 接口说明文档

    注意 所有api的域名为 http 如果后面文档中 有的域名地址和这里不一样 以这里的为主 获取图文资讯 地址 api getnewlist 作用描述 主要用来获取点击首页上的 新闻资讯 后进入到的图文列表页面的数据 大家在做的时候可以使用
  • Cesium defaultAccessToken 修改

    engine Source Core Ion js中修改 defaultAccessToken 值即可 token申请地址 Cesium ion
  • 如何配置anaconda中环境的路径

    如何配置anaconda中环境的路径 虚拟环境安装在C盘绝对不是一种正确的决定 但是如何指定虚拟环境的路径呢 1 先查阅anaconda文档 发现可以指定路径安装 conda create help 2 安装虚拟环境到指定路径中 conda
  • Jquery鼠标右键插件contextMenu使用方法及自定义图标

    第一步 引入文件 文件在github上下载的 都可以搜到 我是把整个dist文件夹里的全放进项目里了 把这俩文件引进去 position js文件我没有引 暂时不知道这文件干啥用的 js部分 contextMenu selector lis
  • 如何组织项目目录结构——项目目录结构规范

    为什么要规范项目目录结构 首先我们要遵循约定由于配置的原则 通过约定代码结构或者命名规范来减少配置数量 例如 将所有 css后缀的文件放在css文件夹下 将xx js文件压缩后的重新命名为xx min js 那怎么样的目录结构是好的呢 没有
  • 【PTA】 sdut-array2-2-局部峰值

    给定一个N行乘N列的2D数组 逐行扫描该值并打印出所有局部峰值 该值大于其左上 上 右上 左 右 左下 下 右下的值 如果有 N的范围是2到150 输入格式 多组输入 每组输入包含两部分 第一行包含整数N 表示2D数组的大小 后面的N行中的
  • css h5 端弹窗时禁止底部页面滚动

    h5 端页面在弹窗时禁止底部页面滚动 在实现时 我尝试过几种方法 方法一 touchmove stop prevent 在遮罩层中添加 touchmove stop prevent 可以实现禁止页面滚动 如下 div class dialo
  • C++中的几种构造函数

    以下内容主要摘抄博客 浅谈C 中的几种构造函数 林多 CSDN博客 c 构造函数 一 C 中的构造函数可以分为4类 1 默认构造函数 又名缺省构造函数 以Student类为例 默认构造函数的原型为 无参构造函数 Student 没有参数 2
  • 使用element-ui的el-scrollbar时滚动条没有显示出来但是页面可以滚动的解决办法

    如果使用 Element UI 的 el scrollbar 组件时 滚动条没有显示出来但页面可以滚动 可以尝试调用其 update 方法来更新滚动条 在适当的时机 例如在数据加载完成后或组件更新后 调用 el scrollbar 的 up
  • Selenium入门(一)Java 搭建 Selenium 环境

    前言 Selenium是一个用于Web应用程序测试的工具 Selenium测试直接运行在浏览器中 就像真正的用户在操作一样 支持的浏览器包括IE 7 8 9 10 11 Mozilla Firefox Safari Google Chrom
  • SpringBoot全局异常处理

    需求 程序运行中可能出现各种错误 如果不对错误进行处理 那么客户端的体验会非常不好 但如果在业务代码中进行了太多的错误处理 造成代码臃肿 后期维护困难 因此 有必要进行全局的异常捕获 统一处理异常状况 工具类 HTTP状态码工具类 pack