异常封装类统一后端响应的数据格式

异常封装类 如何统一后端响应的数据格式

1. 背景

后端作为数据的处理和响应,如何才能和前端配合好,能够高效的完成任务,其中一个比较重要的点就是后端返回的数据格式。

没有统一的响应格式:

// 第一种:
{"data": -1
}// 第二种:
{"timestamp": "2021-07-08T08:05:15.423+00:00","status": 500,"error": "Internal Server Error","path": "/wrong"
}// 第三种:
hello,javadaily

如果你作为一个后端开发的人员将这样式的数据返回给前端的话,那你肯定会被骂屎,如果前后端都是你干那当我没说,所以一个格式规范的响应是至关重要的

有统一的响应格式:

// 规范的返回响应的格式
{"message":"ok","code": 0,"data":{"id": 007,"userName": "xdm"}
}

认识到了响应格式的规范性那么我们就来讲解一个如何实现

2. 代码实现

  1. 实现逻辑

    • 编写一个异常信息枚举类(自定义错误码),将所有可能出现的异常信息通过枚举的方式列出来,方便后续使用
    • 编写一个通用的异常返回类(构建一个语法糖)参数可以是自定义的也可以是枚举类传入的
    • 编写一个异常返回的工具类,包含成功的返回和失败的返回
    • 编写一个基础的异常类来继承运行时异常(目的就是为了能被全局异常处理器捕获到)
    • 编写一个全局异常处理器通过ExceptionHandler来识别到不同的异常(自定的异常还是运行时异常)
  2. 具体实现

    1. 自定义错误码

      public enum ErrorCode {SUCCESS(0, "ok"),PARAMS_ERROR(40000, "请求参数错误"),NOT_LOGIN_ERROR(40100, "未登录"),NO_AUTH_ERROR(40101, "无权限"),NOT_FOUND_ERROR(40400, "请求数据不存在"),SYSTEM_ERROR(50000, "系统内部异常"),OPERATION_ERROR(50001, "操作失败");/*** 错误信息*/private final String message;/*** 状态码*/private final int code;ErrorCode(int code, String message) {this.message = message;this.code = code;}public String getMessage() {return message;}public int getCode() {return code;}
      }
      
    2. 通用的异常返回类

      // 在返回的类型中 数据data的响应是一个泛型
      public class BaseResponse<T> implements Serializable {private static final long serialVersionUID = -3209965291812271422L;// 异常详细信息private String message;// 异常编码private int code;// 异常数据  泛型private T data;public BaseResponse(int code, T data, String message) {this.code = code;this.data = data;this.message = message;}// 不传错误信息的构造方法public BaseResponse(int code, T data) {this(code, data, "");}// 通过枚举类来作为异常参数传入public BaseResponse(ErrorCode errorCode) {this(errorCode.getCode(), null, errorCode.getMessage());}
      }
      
    3. 返回工具类

      public class ResultUtils {/*** 成功的返回   需要使用泛型进行数据的返回* @param data* @return* @param <T>*/public static <T> BaseResponse<T> success(T data) {return new BaseResponse(0, data, "ok");}/*** 失败的返回 使用自定义错误码* @param errorCode* @return*/public static BaseResponse error(ErrorCode errorCode) {return new BaseResponse(errorCode.getCode(), null, errorCode.getMessage());}/*** 失败的返回  没有使用自定义错误码  自定义的异常信息 + 错误码* @param code* @param message* @return*/public static BaseResponse error(int code, String message) {return new BaseResponse(code, null, message);}/*** 自定义错误码 + 自定义的异常信息* @param errorCode* @param message* @return*/public static BaseResponse error(ErrorCode errorCode, String message) {return new BaseResponse(errorCode.getCode(), null, message);}
      }
      
    4. 基础的异常类来继承运行时异常(实现全局异常处理)

      public class BusinessException extends RuntimeException {/*** 错误码*/private final int code;/*** 错误码和错误信息的构造方法* @param code* @param message*/public BusinessException(int code, String message) {super(message);this.code = code;}/*** 通过传入的自定义错误码*/public BusinessException(ErrorCode errorCode) {super(errorCode.getMessage());this.code = errorCode.getCode();}/*** 自定义错误码 + 自定义异常消息* @param errorCode* @param message*/public BusinessException(ErrorCode errorCode, String message) {super(message);this.code = errorCode.getCode();}public int getCode() {return code;}
      }
    5. 全局异常处理器

      @RestControllerAdvice // 实现bean注入
      @Slf4j/*** 全局异常处理器*/
      public class GlobalExceptionHandler {/*** 自定义的异常* @param e* @return*/@ExceptionHandler(BusinessException.class)public BaseResponse<?> businessExceptionHandler(BusinessException e) {log.error("BusinessException: ", e);return ResultUtils.error(e.getCode(), e.getMessage());}/*** 运行时异常  系统异常* @param e* @return*/@ExceptionHandler(RuntimeException.class)public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {log.error("RuntimeException: ", e);return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误");}
      }

      至此一个全局异常的处理我们就实现了,能够在后续的代码编写中方便的返回我们的数据并且规范

3. 具体使用

在正确的返回,最终结果的返回的时候我们只需要使用异常工具类调用其中的成功的响应方法即可;失败的返回我们需要通过抛出异常的形式进行返回,然后全局异常处理器就能捕获到异常并输出。

 @PostMapping("/register")// 这里使用通用的异常类的类型public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userLoginRequest) {if(userLoginRequest == null) {// 这里通过基础异常类来进行返回它继承的是运行时异常会被全局异常处理器捕获到// 传入的参数就是我们自定义的错误码(枚举)throw new BusinessException(ErrorCode.PARAMS_ERROR);}String userAccount = userLoginRequest.getUserAccount();String userPassword = userLoginRequest.getUserPassword();String checkPassword = userLoginRequest.getCheckPassword();if(StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {throw new BusinessException(ErrorCode.PARAMS_ERROR);}long result = userService.userRegister(userAccount, userPassword, checkPassword);// 成功的返回 使用异常工具类return ResultUtils.success(result);}

我们在使用在线接口文档进行测试的时候就能看到返回的数据是我们想要的格式

image-20240614165426295

总结:

​ 到这里整个异常类的统一处理就实现了,我们可以将这段代码自己保留下来然后直接复制到其他的项目上复用,这样你距离cv工程师又又又近了一步。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数 组

概述 数组是一个引用类型&#xff0c;是一种容器。 数组存储多个相同数据类型的数据&#xff0c;允许自动类型转换。例如 int 类型的数组&#xff0c;可以存放 byte、short 和 int 类型的数据&#xff0c;double 类型的数组&#xff0c;可以存放 byte、short、int、long、floa…

【Apache Doris】周FAQ集锦:第 5 期

【Apache Doris】周FAQ集锦&#xff1a;第 5 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

zip加密txt文件后,暴力破解时会有多个解密密码可以打开的疑问??

最近在做一个关于zip压缩文件解密的测试&#xff0c;发现通过暴力解密时&#xff0c;会有多个解密密码可以打开&#xff0c;非常疑惑&#xff0c;这里做个问题&#xff0c;希望能有大佬解惑。 1、首先在本地创建一个113449.txt的文件&#xff0c;然后右键txt文件选择压缩&…

1586. 扫地机器人

问题描述 Mike同学在为扫地机器人设计一个在矩形区域中行走的算法,Mike是这样设计的:先把机器人放在出发点 (1,1)(1,1) 点上,机器人在每个点上都会沿用如下的规则来判断下一个该去的点是哪里。规则:优先向右,如果向右不能走(比如:右侧出了矩形或者右侧扫过了)则尝试向…

为什么说Python 是胶水语言?

​ "Python 是胶水语言"这一说法是指它很擅长将不同的程序或代码库连接在一起&#xff0c;能够让来自不同编程语言或框架的组件无缝协作。Python 具有丰富的库和简单的语法&#xff0c;使得它可以轻松调用其他语言编写的程序或使用不同技术栈的模块。 ​ 以下是几个…

Linux C编译器从零开发二

自定义分词器 test.c #include <ctype.h> #include <stdarg.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h>typedef enum {TK_PUNCT, // PunctuatorsTK_NUM, // Numeric literalsTK_EOF, // …

线上教育培训办公系统系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;教师管理&#xff0c;学生管理&#xff0c;运营事件管理 教师账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;作业管理&#xff0c;电…

用CloudCompare软件拟合点云中的圆柱体

用CloudCompare软件拟合点云中的圆柱体 软件下载 点击下面的链接&#xff0c;进入下载页面&#xff1a; 下载页面 然后根据需要选择下载合适的软件版本。 一般选择windows installer版&#xff0c;如图所示&#xff1a; 下载完成后&#xff0c;安装并打开软件。软件的默认语…

【MySQL】在CentOS环境下安装MySQL

目录 一、卸载残留环境 二、获取官方yum源 三、安装yum源 四、安装MySQL 五、启动MySQL 一、卸载残留环境 输入 ps axj | grep mysql 查看是否存在正在运行的MySQL服务 如果有&#xff0c;则先输入 systemctl stop mysqld 来关闭服务 然后输入 rpm -qa | grep mysql 查看…

XGBoost预测及调参过程(+变量重要性)--血友病计数数据

所使用的数据是血友病数据&#xff0c;如有需要&#xff0c;可在主页资源处获取&#xff0c;数据信息如下&#xff1a; 读取数据及数据集区分 数据预处理及区分数据集代码如下&#xff08;详细预处理说明见上篇文章--随机森林&#xff09;&#xff1a; import pandas as pd im…

SQLServer 借助Navcate做定时备份的脚本

首先创建SQLServer链接&#xff0c;然后在Query标签种创建一个查询 查询内容如下 use ChengYuMES declare ls_time varchar(1000) declare ls_dbname varchar(1000) set ls_time convert(varchar, getdate(), 112) _ replace(convert(varchar, getdate(), 108), :, )-- 需…

68. UE5 RPG 优化敌人角色的表现效果

我们现在已经有了四个敌人角色&#xff0c;接下来&#xff0c;处理一下在战斗中遇到的问题。 处理角色死亡后还会攻击的问题 因为我们有角色溶解的效果&#xff0c;角色在死亡以后的5秒钟才会被销毁掉。所以在这五秒钟之内&#xff0c;角色其实还是会攻击。主要时因为AI行为树…

LeetCode 算法:回文链表 c++

原题链接&#x1f517;&#xff1a;回文链表 难度&#xff1a;简单⭐️ 题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head…

C++11移动语义

前言 之前我们已经知道了在类里开辟数组后&#xff0c;每一次传值返回和拷贝是&#xff0c;都会生成一个临时变量 class Arr { public://构造Arr() {/*具体实现*/ };//拷贝Arr(const Arr& ar) {/*具体实现*/ };//重载Arr operator(const Arr& ar) { /*具体实现*/Arr …

Python高级编程:Functools模块的8个高级用法,强烈建议添加到你的开发工具箱中!

目录 1. functools.partial 2. functools.lru_cache lru_cache的特点 cache的特点 性能比较与选择 3. functools.reduce functools.reduce的作用 工作原理 示例 累加序列中的所有元素 计算阶乘 initializer的使用 应用场景 示例:计算平均销售额 小结 4. funct…

微前端乾坤方案

微前端乾坤方案 了解乾坤 官方文档 介绍 qiankun 是一个基于 single-spa 的微前端实现库&#xff0c;旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 qiankun 的核心设计理念 &#x1f944; 简单 由于主应用微应用都能做到技术栈无关&#xff0c;qiankun 对…

Java 桥接模式(Bridge Pattern)是设计模式中的一种结构型设计模式,桥接模式的核心思想是将抽象与实现解耦

桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立地变化。桥接模式的核心思想是将抽象与实现解耦&#xff0c;使得它们可以独立扩展。 在桥接模式中&#xff0c;通常包含以下四个…

DAY3-力扣刷题

1.罗马数字转整数 13. 罗马数字转整数 - 力扣&#xff08;LeetCode&#xff09; 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L …

最长不下降子序列LIS详解

最长不下降子序列指的是在一个数字序列中&#xff0c;找到一个最长的子序列&#xff08;可以不连续&#xff09;&#xff0c;使得这个子序列是不下降&#xff08;非递减&#xff09;的。 假如&#xff0c;现有序列A[1&#xff0c;2&#xff0c;3&#xff0c;-1&#xff0c;-2&…

16.大模型分布式训练框架 Microsoft DeepSpeed

微调、预训练显存对比占用 预训练LLaMA2-7B模型需要多少显存&#xff1f; 假设以bf16混合精度预训练 LLaMA2-7B模型&#xff0c;需要近120GB显存。即使A100/H100&#xff08;80GB&#xff09;单卡也无法支持。 为何比 QLoRA多了100GB&#xff1f;不妨展开计算下显存占用&…