Springboot配置全局异常通用返回

Springboot配置全局异常通用返回

前言

前端对接了部分接口后,开始抱怨,“后端接口出参的格式总是千奇百怪,没有一个固定的格式,错误信息提示也不明朗,业务的状态码总是东一个西一个,前端这都不好做统一的管理操作”,对此后端开始研究起对出参的统一封转。

约定统一的格式

通过对所有的出参都有固定的格式输出,可以让前端封装拦截器来对请求不同逻辑走向的处理。

简单的业务状态+详情出参

code 约定为业务结果码 2000成功,5000失败message 约定为错误提示信息,data 约定为返回的出参内容。对此就形成了固定的出参json格式如下:

{
    "code":2000,
    "message":"成功",
    "data":{}
}

前端可以根据不同的code返回,做不同逻辑处理

  • code = 2000 , 做成功data数据内容的展示
  • code = 5000 , 做失败的提示语message提示

通过Http状态码判断

针对特殊场景的判定,可以根据Http状态码来判断,因为每个请求都有对应的http请求的状态码返回,例如200,500,401,404等常用的状态码,也能当作前端判断请求的情况的依据。

  • 2xx(成功状态码)
    • 200 (OK):请求成功
    • 201 (Created):请求成功,服务器对应资源已创建
    • 202 (Accepted):服务器接受请求,但还没处理好
    • 204 (No Content): 服务器成功处理请求,但没有内容返回
    • 205 (Reset Content): 服务器成功处理请求,要求客户端重置之前显示内容
    • 206 (Partial Content): 服务器成功处理部分请求,用于断点续传
  • 3xx(重定向状态码)
    • 301 (Moved Permanently): 请求资源已经换成新的url,望客户端请求新的地址Location的url
    • 302 (Found): 请求资源暂时换成新的url
    • 304 (Not Modified) : 服务端判断是否资源没被修改,浏览器使用本地缓存
  • 4xx(客户端错误状态码)
    • 400 (Bad Request) :客户端请求格式有问题
    • 401 (Unauthorized) : 未认证或者认证失败
    • 403 (Forbidden) : 没有对应的权限
    • 404 (Not Found): 服务器找不到对应的客户端请求的资源
    • 405 (Method Not Allowed) : 客户端请求方法不被服务端允许要求的
  • 5xx(服务端错误状态码)
    • 500 (Internal Server Error) : 服务器内部程序代码等引起的错误
    • 502 (Bad Gateway):作为网关,收到服务器无效的响应
    • 503 (Service Unavailable) : 服务器无法提供服务
    • 504 (Gateway Time - out) : 作为网关,收到服务器响应超时过慢

复杂展示的业务场景

对于单一code无法描述的场景,可以再额外增添参数来描述具体的场景情况。

  • errorDetails: 错误对象具体字段描述,在指定code为4000-4999之前的错误是有
    • field : 指定具体错误字段
    • errorMsg: 指定具体错误信息
  • timestamp(可选) : 记录请求时间
  • version(可选) :记录接口版本
  • traceId(可选):记录链路追踪id
{
    "code":4000,
    "message":"提交格式错误"
    "data":null,
    "errorDetails":[
         {
             "field":"username",
             "errorMsg":"名称必须在6-20个字符内"
         }
    ]
}

message字段提供一个整体的错误概述,errorDetails则提供具体的错误细节,两者结合可以让前端更全面地了解错误情况

封装常量的案例

请求状态码的枚举值

@Getter
public enum ResultEnum {

    SUCCESS("请求成功", 2000),
    ERROR("服务器内部错误", 5000),
    PARAM_ERROR("参数错误", 4001),
    ;

    private String msg;
    private Integer code;

    ResultEnum(String msg, Integer code) {
        this.msg = msg;
        this.code = code;
    }
}

统一出参的格式封装

@Data
public class ResultData<T> {

    /**
     * 默认生成的序列号
     */
    private static final long serialVersionUID = 1L;
    private Integer code = 2000;//默认成功
    private String msg = "";
    private T data;

    public ResultData(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public ResultData(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> ResultData<T> error(Integer code, String msg) {
        return new ResultData<T>(code, msg);
    }

    public static <T> ResultData<T> error(String msg) {
        return new ResultData<T>(ResultEnum.ERROR.getCode(), msg);
    }

    public static <T> ResultData<T> success(String msg) {
        return new ResultData<T>(ResultEnum.SUCCESS.getCode(), msg);
    }

    public static <T> ResultData<T> success(String msg, T data) {
        return new ResultData<T>(ResultEnum.SUCCESS.getCode(), msg, data);
    }


}

全局异常处理

@RestControllerAdvice是 Spring 框架提供的用于全局异常处理的注解 ,通过该注解可以是实现集中在一个类中处理异常的问题,避免重复处理异常代码 , 在具体的方法上使用@ExceptionHandler针对性的处理不同异常导致的问题

使用方式

@RestControllerAdvice 
public class GlobalExceptionHandlerAdvice {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultData<Object> resolveMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        FieldError fieldError = e.getBindingResult().getFieldError();
        log.error("【参数校验异常】错误提示:{}", fieldError != null ? fieldError.getDefaultMessage() : "");
        return ResultData.error(ResultEnum.PARAM_ERROR.getCode(), e.getBindingResult().getFieldError().getDefaultMessage());
    }
}

例如对于之前使用参数校验时@Valid@Validated进行参数验证失败的情况,抛出的MethodArgumentNotValidException异常,就会统一到上述这个方法上处理,bindingResult中能获取到错误的字段和错误的信息,将其打印出来和结果值返回给前端

常见的需补充的错误异常

还有一些其他异常,可以选择性的对其进行一一的处理封装成ResultData返回给前端,最后兜底使用Exception处理异常保证最后输出还是为统一格式。

  • SQLExceptionDataAccessException : 与数据库交互过程中产生的异常
  • HttpRequestMethodNotSupportedException : 请求方式不支持的异常
  • MethodArgumentNotValidException、 ConstraintViolationException : 使用@Valid@Validated时校验参数时可能会遇到的异常
  • HttpMessageNotReadableExceptionHttpMessageNotWritableException : 请求体的数据读写导致的问题
  • IllegalArgumentException : 参数格式错误的异常
  • CustomeException(自定义异常):自定义实现标识特定异常错误
  • Exception : 最后兜底顶级的异常,保证异常处理最后会走到的地方

ExceptionHandler 处理异常优先级

处理的优先级,必然是有精确匹配到的异常处理方法先走,如果没有精确匹配的异常处理,会根据子类->父类的顺序来处理 。

如有如下三种异常,ExceptionA,ExceptionB,ExceptionC ,分别是ExceptionA 是 ExceptionB的父类,ExceptionB是ExceptionC的父类 ,

@ExceptionHandler(ExceptionA.class)
@ResponseBody
public ResultData<Object> ExceptionASolve(ExceptionA e) {
}

@ExceptionHandler(ExceptionB.class)
@ResponseBody
public ResultData<Object> exceptionBSolve(ExceptionB e) {
}
@RequestMapping("/hello")
public String hello() {
    throw new ExceptionC("sss");
}

此时对应请求抛出ExceptionC,全局处理异常方法exceptionBSolve会去对应处理它

注意: 当然还有另外一种情况,你在方法体里定义对同一个异常处理下有多个方法,会导致最后执行到哪个方法是属于不确定性的,因为会取决于方法的定义顺序,类的加载顺序等因素。

总结

和前端沟通设计好统一的返回模板,便于前端进行交互,一般场景下,可以直接使用简单的通用模板来返回。针对额外复杂的场景可以适当的增加参数做区分判断。还有就是对异常进行统一的集中处理,封装成模板返回给前端。

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

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

相关文章

[vulnhub] Corrosion: 2

https://www.vulnhub.com/entry/corrosion-2,745/ 提示&#xff1a;枚举才是神 主机发现端口扫描 使用nmap扫描网段类存活主机 因为靶机是我最后添加的&#xff0c;所以靶机IP是6 &#xff0c;kali是10 nmap -sP 192.168.56.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) …

MySQL数据库的备份与还原

目录 mysql 数据库的备份 生成SQL脚本 1 在控制台使用mysqldump命令可以用来生成指定数据库的脚本 ​编辑2 在数据库图形化界面工具&#xff1a;DateGrip 中操作&#xff1a;导出 mysql 数据库的还原 执行SQL脚本 1 在控制台使用 命令&#xff0c;指定将sql脚本导入到指定…

ASR 点亮闪光灯和后摄对焦马达

ASR翱捷科技 ASR kernel 5.10 android14 ASR EVB平台 ASR 原理图 闪光灯是gpio控制 1.驱动 路径:asr\kernel\linux\drivers\media\platform\asr-mars11\flash\leds-gpio-flash.c 驱动加载后生成设备节点/sys/class/leds/torch 和/sys/class/leds/flash。 Makefile Kconfig…

【大数据学习 | HBASE】hbase的读数据流程与hbase读取数据

1. hbase的读数据流程 在解析读取流程之前我们还需要知道两个功能性的组件和HFIle的格式信息 HFILE 存储在hdfs中的hbase文件&#xff0c;这个文件中会存在hbase中的数据以kv类型显示&#xff0c;同时还会存在hbase的元数据信息&#xff0c;包括整个hfile文件的索引大小&…

【GPTs】MJ Prompt Creator:轻松生成创意Midjourney提示词

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;GPTs指令&#x1f4af;前言&#x1f680; MJ Prompt Creator主要功能适用场景优点缺点 &#x1f4af; 小结 &#x1f4af;GPTs指令 中文翻译&#xff1a; 任务说明 您是一款为幻灯片…

实现3D热力图

实现思路 首先是需要用canvas绘制一个2D的热力图&#xff0c;如果你还不会&#xff0c;请看json绘制热力图。使用Threejs中的canvas贴图&#xff0c;将贴图贴在PlaneGeometry平面上。使用着色器材质&#xff0c;更具json中的数据让平面模型 拔地而起。使用Threejs内置的TWEEN&…

ATom: 矿物粉尘在卷云形成中的主导作用

目录 ATom: Dominant Role of Mineral Dust in Cirrus Cloud Formation 简介 摘要 代码 引用 网址推荐 知识星球 机器学习 ATom: Dominant Role of Mineral Dust in Cirrus Cloud Formation 简介 该数据集提供了&#xff1a;&#xff08;1&#xff09;由 NOAA 粒子分析…

C语言 | Leetcode C语言题解之第560题和为K的子数组

题目&#xff1a; 题解&#xff1a; // 暴力美学&#xff1a;20行C代码 int subarraySum(int *nums, int numsSize, int k) {int count 0;// 弄个大数组做个暴力的Hash表&#xff0c;大概4*20M*2160M。用calloc初始化为全零。int *maps (int *)calloc(1001 * 20001 * 2, siz…

基于vue框架的的社区居民服务管理系统8w86o(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;居民,楼房信息,报修信息,缴费信息,维修进度 开题报告内容 基于Vue框架的社区居民服务管理系统开题报告 一、研究背景与意义 随着城市化进程的加速&#xff0c;社区居民数量激增&#xff0c;社区管理面临着前所未有的挑战。传统的社区…

UE5.4 PCG 自定义PCG蓝图节点

ExecuteWithContext&#xff1a; PointLoopBody&#xff1a; 效果&#xff1a;点密度值与缩放成正比

[ Linux 命令基础 2 ] Linux 命令详解-系统管理命令

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

单链表算法题(数据结构)

1. 反转链表 https://leetcode.cn/problems/reverse-linked-list/description/ 题目&#xff1a; 看到这个题目的时候我们怎么去想呢&#xff1f;如果我们反应快的话&#xff0c;应该可以想到我们可以从1遍历到5然后依次头插&#xff0c;但是其实我们还有更好的办法&#xff…

Java代码审计-模板注入漏洞

一、模板引擎 在Java开发当中&#xff0c;为了将前端和后端进行分离&#xff0c;降低项目代码的耦合性&#xff0c;使代码更加易于维护和管理。除去以上的原因&#xff0c;模板引擎还能实现动态和静态数据的分离。 二、主流模板引擎 在Java中&#xff0c;主流的模板引擎有:Fre…

SQLI LABS | Less-39 GET-Stacked Query Injection-Intiger Based

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-39/ 本关是堆…

《深度学习》——深度学习基础知识(全连接神经网络)

文章目录 1.神经网络简介2.什么是神经网络3.神经元是如何工作的3.1激活函数3.2参数的初始化3.2.1随机初始化3.2.2标准初始化3.2.3Xavier初始化&#xff08;tf.keras中默认使用的&#xff09;3.2.4He初始化 4.神经网络的搭建4.1通过Sequential构建神经网络4.2通过Functional API…

备战软考Day05-数据库系统基础知识

一、基本概念 1.数据库 数据库(Database&#xff0c;缩写为DB)是指长期存储在计算机内的、有组织的、可共享的数据集合。数据库中的数据按一定的数据模型组织、描述和存储&#xff0c;具有较小的冗余度、较高的数据独立性和易扩展性&#xff0c;并可为各种用户共享。 2.数据…

Spark 的容错机制:保障数据处理的稳定性与高效性

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…

NLP论文速读(NeurIPS2024)|使用视觉增强的提示来增强视觉推理

论文速读|Enhancing LLM Reasoning via Vision-Augmented Prompting 论文信息&#xff1a; 简介: 这篇论文试图解决的问题是大型语言模型&#xff08;LLMs&#xff09;在处理包含视觉和空间线索的推理问题时的局限性。尽管基于LLMs的推理框架&#xff08;如Chain-of-Thought及其…

在 RHEL 8 | CentOS Linux release 8.5.2111上安装 Zabbix 6

1. 备份YUM源文件 cd /etc/yum.repos.d/ mkdir bak mv C* ./bak/ wget -O /etc/yum.repos.d/CentOS-Linux-BaseOS.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo yum clean all yum makecache2. 将 SELinux 设置为宽容模式&#xff0c;如下所示。 sudo s…

在 Mac 和 Windows 系统中快速部署 OceanBase

OceanBase 是一款分布式数据库&#xff0c;具备出色的性能和高扩展性&#xff0c;可以为企业用户构建稳定可靠、灵活扩展性能的数据库服务。本文以开发者们普遍熟悉的Windows 或 Mac 环境为例&#xff0c;介绍如何快速上手并体验OceanBase。 一、环境准备 1. 硬件准备 OceanB…