SpringBoot教程(八) | SpringBoot统一结果封装
SpringBoot教程(八) | SpringBoot统一结果封装
经过了前面几篇文章,SpringBoot中MVC相关的配置其实都已经差不多了,接下来就可以完全进入接口开发阶段了。前面我们写过几个接口,虽然都加了@RestController注解,相当于统一了我们的返回数据的基本形式为JSON,但是由于我们的项目可能是很多人一起开发,所以我们最好能够把我们的返回结果统一一下,让大家都返回一样的数据格式,这样即规范了代码,也方便了前端人员的调用,不然每个人都按照每个人的风格去写,代码会变得非常混乱。
那我我们怎么还封装这个结果呢,那就要关注我们返回给前端的数据都要包含哪些信息。
一般来讲,首先要有一个code, 用来代表我们这次接口的一个状态,比如 0代表成功,1代表失败,2代表必传参数不对, 4代表系统异常等等。这只是个简单的举例。可能很多人会有疑问,Http协议本身不是已经有了相应的返回码的定义了么,比如200代表成功, 500代表服务器错误,404代表找不到页面,为啥咱们还要在定义呢,这就是划分粒度的问题了,就那200来说,它代表是这次请求成功了,但是它描述不了这次请求中的业务结果,比如用户名已存在,其实业务上就不是一种成功,但http的结果肯定是200,所以我们需要一种描述我们业务状态的编码。
除了编码之外,还有要一些提示信息,比如,操作成功,系统异常,用户名已存在等,所以我们再加一个messge字段。
还有什么呢,还有我们的核心数据,比如我根据id获取数据,那个这个数据的具体内容,我们肯定是必须要返回给前端呢,所以还要 有个data, 那这个data 用什么类型呢,这个类型肯定是五花八门,所以我们要用一个统一的父类,Object才可以接收所有类型,当然为了便于操作我们可以采用泛型的方式。
通过上面的分析,我们的这个类基本上就已经可以设计出来了。
java复制代码public class Result<T> implements Serializable {private static final long serialVersionUID = -3960261604605958516L;private int code;private String msg;private T data;// get set方法,限于篇幅问题,这里不写了,大家操作的时候自己生成一下。或者使用lombokpublic static <T> Result<T> success() {return new Result<>();}/*** 成功,默认状态码,返回消息,自定义返回数据** @param data 自定义返回数据* @param <T> 返回类泛型,不能为String* @return 通用返回Result*/public static <T> Result<T> success(T data) {return new Result<>(data);}/*** 成功,默认状态码,自定义返回消息,无返回数据** @param msg 自定义返回消息* @param <T> 返回类泛型* @return 通用返回Result*/public static <T> Result<T> success(String msg) {return new Result<>(msg);}/*** 成功,默认状态码,自定义返回消息,返回数据** @param msg 自定义返回消息* @param data 自定义返回数据* @param <T> 返回类泛型* @return 通用返回Result*/public static <T> Result<T> success(String msg, T data) {return new Result<>(msg, data);}/*** 失败,默认状态码,返回消息,无返回数据** @param <T> 返回类泛型* @return 通用返回Result*/public static <T> Result<T> error() {return new Result<>(ResultCode.ERROR);}/*** 失败,默认状态码,自定义返回消息,无返回数据** @param <T> 返回类泛型* @return 通用返回Result*/public static <T> Result<T> error(String msg) {return new Result<>(ResultCode.ERROR.getCode(), msg);}/*** 失败,自定义状态码,返回消息,无返回数据** @param code 自定义状态码* @param msg 自定义返回消息* @param <T> 返回类泛型* @return 通用返回Result*/public static <T> Result<T> error(int code, String msg) {return new Result<>(code, msg);}/*** 失败,使用CodeMsg状态码,返回消息,无返回数据** @param resultCode CodeMsg,参数如下:* <p> code 状态码* <p> msg 返回消息* @param <T> 返回类泛型* @return 通用返回Result*/public static <T> Result<T> error(ResultCode resultCode) {return new Result<>(resultCode);}/*** 成功构造器,无返回数据*/private Result() {this(ResultCode.SUCCESS);}/*** 成功构造器,自定义返回数据** @param data 返回数据*/private Result(T data) {this(ResultCode.SUCCESS, data);}/*** 成功构造器,自定义返回消息,无返回数据** @param msg 返回消息*/private Result(String msg) {this(ResultCode.SUCCESS.getCode(), msg);}/*** 成功构造器,自定义返回信息,返回数据** @param msg 返回信息* @param data 返回数据*/private Result(String msg, T data) {this(ResultCode.SUCCESS.getCode(), msg, data);}/*** 构造器,自定义状态码,返回消息** @param code 状态码* @param msg 返回消息*/private Result(int code, String msg) {this.code = code;this.msg = msg;}/*** 构造器,自定义状态码,返回消息,返回数据** @param code 状态码* @param msg 返回消息* @param data 返回数据*/private Result(int code, String msg, T data) {this(code, msg);this.data = data;}/*** 构造器,使用CodeMsg状态码与返回信息** @param resultCode CodeMsg,参数如下:* <p> code 状态码* <p> msg 返回消息*/private Result(ResultCode resultCode) {this(resultCode.getCode(), resultCode.getMsg());}/*** 构造器,使用CodeMsg状态码与返回信息,自定义返回数据** @param resultCode CodeMsg,参数如下:* <p> code 状态码* <p> msg 返回消息* @param data 返回数据*/private Result(ResultCode resultCode, T data) {this(resultCode);this.data = data;}}
在定义几个常见的错误:这里为了不写那么多的get,set,我们引入了lombok
java复制代码@Data
@Builder
public class ResultCode implements Serializable {private static final long serialVersionUID = -6269841958947880397L;/*** 状态码*/private int code;/*** 状态信息*/private String msg;/*** 默认成功*/public final static ResultCode SUCCESS = dispose(ResultCodeEnum.SUCCESS);/*** 默认失败*/public final static ResultCode ERROR = dispose(ResultCodeEnum.ERROR);/*** 通用业务异常*/public final static ResultCode BIZ_ERROR = dispose(ResultCodeEnum.BIZ_ERROR);/*** 文件超出最大限制*/public final static ResultCode FILE_OUT_MAX = dispose(ResultCodeEnum.FILE_OUT_MAX);/*** 文件格式不正确*/public final static ResultCode FILE_FORMAT_ERROR = dispose(ResultCodeEnum.FILE_FORMAT_ERROR);/*** 参数错误*/public final static ResultCode PARAM_ERROR = dispose(ResultCodeEnum.PARAM_ERROR);/*** Json解析异常*/public final static ResultCode JSON_FORMAT_ERROR = dispose(ResultCodeEnum.JSON_FORMAT_ERROR);/*** Sql解析异常*/public final static ResultCode SQL_ERROR = dispose(ResultCodeEnum.SQL_ERROR);/*** 网络超时*/public final static ResultCode NETWORK_TIMEOUT = dispose(ResultCodeEnum.NETWORK_TIMEOUT);/*** 未知的接口*/public final static ResultCode UNKNOWN_INTERFACE = dispose(ResultCodeEnum.UNKNOWN_INTERFACE);/*** 请求方式不支持*/public final static ResultCode REQ_MODE_NOT_SUPPORTED = dispose(ResultCodeEnum.REQ_MODE_NOT_SUPPORTED);/*** 系统异常*/public final static ResultCode SYS_ERROR = dispose(ResultCodeEnum.SYS_ERROR);private static ResultCode dispose(ResultCodeEnum codeEnum) {return ResultCode.builder().code(codeEnum.getCode()).msg(codeEnum.getMsg()).build();}public ResultCode(int code, String msg) {this.code = code;this.msg = msg;}
}
java复制代码public enum ResultCodeEnum {SUCCESS(0, "操作成功"),ERROR(1, "操作失败"),BIZ_ERROR(1000, "通用业务异常"),FILE_OUT_MAX(9000, "文件超出最大限制"),FILE_FORMAT_ERROR(9001, "文件格式不正确"),PARAM_ERROR(9050, "参数错误"),JSON_FORMAT_ERROR(9051, "Json解析异常"),SQL_ERROR(9052, "Sql解析异常"),NETWORK_TIMEOUT(9510, "网络超时"),UNKNOWN_INTERFACE(9520, "未知的接口"),REQ_MODE_NOT_SUPPORTED(9530, "请求方式不支持"),SYS_ERROR(9999, "系统异常");/*** 状态码*/private final int code;/*** 状态信息*/private final String msg;public int getCode() {return code;}public String getMsg() {return msg;}ResultCodeEnum(int code, String msg) {this.code = code;this.msg = msg;}
}
这个写完了以后,就可以统一我们的返回结果,以后所有的Controller就都要返回Result类型。比如:
java复制代码@GetMapping("/withinRangeResource")public Result<List<EmergencyExpertResVO>> withinRangeResource(@Valid ResourceRangeReqVO param) {List<EmergencyExpertResVO> expertResVOS = emergencyExpertBiz.getWithinRangeResource(param);return Result.success(expertResVOS);}
另: 配套项目代码已托管中gitCode: gitcode.net/lsqingfeng/…
相关文章:
SpringBoot教程(八) | SpringBoot统一结果封装
SpringBoot教程(八) | SpringBoot统一结果封装 经过了前面几篇文章,SpringBoot中MVC相关的配置其实都已经差不多了,接下来就可以完全进入接口开发阶段了。前面我们写过几个接口,虽然都加了RestController注解,相当于统一了我们的…...

Ubuntu 22.04 安装Fail2Ban
Fail2Ban是一种用来防止暴力破解的工具,一般要和iptables配合使用。其原理是读取系统日志,并通过正则表达式匹配,监控IP在一段时间内的登录尝试、身份验证失败日志等并进行计数。超过阈值则进行IP封禁,过一段时间后再解封。 总的…...

Ubuntu 22.04 编译安装 Qt mysql驱动
参考自 Ubuntu20.04.3 QT5.15.2 MySQL驱动编译 Ubuntu 18.04 编译安装 Qt mysql驱动 下边这篇博客不是主要参考的, 但是似乎解决了我的难题(找不到 libmysqlclient.so) ubuntu18.04.2 LTS 系统关于Qt5.12.3 无法加载mysql驱动,需要重新编译MYSQL数据库驱动的问题以…...

Mindspore 公开课 - CodeGeeX
CodeGeeX: 多语言代码生成模型 CodeGeeX 是一个具有130亿参数的多编程语言代码生成预训练模型。CodeGeeX采用华为MindSpore框架实现,在鹏城实验室“鹏城云脑II”中的192个节点(共1536个国产昇腾910 AI处理器)上训练而成。截至2022年6月22日&…...
说一下mysql的锁
1、全局锁: 影响整个数据库的锁。例如,当执行 FLUSH TABLES WITH READ LOCK; 命令时,会阻止其他用户写入数据库,但可以读取。全局锁简介 全局锁是一种跨所有数据库实例的锁。它可以确保在任何时刻,只有一个事务能够访问共享资源。全局锁通常用于以下场景: 并发性较高的场…...

rime中州韵小狼毫 日期/农历 时间 事件 节气 滤镜
教程目录:rime中州韵小狼毫须鼠管安装配置教程 保姆级教程 100增强功能配置教程 网络上但凡提到 rime中州韵小狼毫须鼠管输入法,总少不了智能时间,日期等炫技,可见这个便捷时间/日期输入功能是多么的受欢迎。作者也不落窠臼&…...

【前端】前后端的网络通信基础操作(原生ajax, axios, fetch)
概述 前后端网络请求工具 原生ajaxfetch apiaxios GET和POST请求 get只能发纯文本 post可以发不同类型的数据,要设置请求头,需要告诉服务器一些额外信息 测试服务器地址 有一些公共的测试 API 可供学习和测试用途。这些 API 允许你发送 HTTP 请求…...

Matter - 配置工厂数据(2)
部分关键名词参数简介 PASE(Passcode-Authenticated Session Establishment): 基于密码认证的会话建立,用于在 Commissioning 的时候 Commissioner 与 Matter Deivce 之间建立安全信道,生成对称加密密钥用于 Commissioning 后续通信消息进行加、解密和完…...

版本控制背景知识
版本控制背景知识 本文是关于 Git 系列文章的导读,我们先介绍一下版本控制的背景知识。 什么是版本控制 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。它将什么时候、什么人更改了文件的什么内容等信息如实记录下来…...

tensorflow报错: DNN library is no found
错误描述 如上图在执行程序的时候,会出现 DNN library is no found 的报错 解决办法 这个错误基本上说明你安装的 cudnn有问题,或者没有安装这个工具。 首先检测一下你是否安装了 cudnn 进入CUDA_HOME下,也就是进入你的cuda的驱动的安装目…...
DA14531-高级应用篇-用户如何开启OTA服务
文章目录 1. OTA相关文件2.OTA宏定义列表3.OTA主要函数接口4.OTA具体实施步骤5.总结1. OTA相关文件 1)app_suotar_task.c和app_suotar_task.h 2)app_suotar.c和app_suotar.h 2.OTA宏定义列表 宏定义注解CFG_PRF_SUOTAR用户开启SOTA功能BLE_SUOTA_RECEIVERSOTA功能服务CFG_S…...

国内镜像源配置方法(包括临时和永久方法)
国内镜像源: 阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/豆瓣 http://pypi.douban.com/simplePython官方 https://pypi.python.org/simple/v2ex http://pypi.v2ex.com/simple/中国科学院 http://pypi.mi…...
数据结构二叉树--堆(数据结构实现和堆排序的一种实现)
堆是一个数据结构 逻辑结构:完全二叉树(要求父节点大于孩子节点或者小于孩子节点) 存储结构:顺序存储 typedef int DataType; typedef struct Heap{DataType*data;int size;int capacity; }Heap;void InitHeap(Heap*pH) {asser…...

【Linux】 nohup命令使用
nohup命令 nohup是Linux和Unix系统中的一个命令,其作用是在终端退出时,让进程在后台继续运行。它的全称为“no hang up”,意为“不挂起”。nohup命令可以让你在退出终端或关闭SSH连接后继续运行命令。 nohup 命令,在默认情况下&…...

多维时序 | Matlab实现GRO-CNN-LSTM-Attention淘金算法优化卷积神经网络-长短期记忆网络结合注意力机制多变量时间序列预测
多维时序 | Matlab实现GRO-CNN-LSTM-Attention淘金算法优化卷积神经网络-长短期记忆网络结合注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现GRO-CNN-LSTM-Attention淘金算法优化卷积神经网络-长短期记忆网络结合注意力机制多变量时间序列预测效果一览基本介绍程序设…...

SQL-DQL-基础查询
🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:重拾MySQL 🍹文章作者技术和水平很有限,如果文中出现错误&am…...

Kubernetes (十三) 存储——持久卷-动静态分配
一. 简介 二. NFS持久化存储步骤(静态分配) 1. 集群外…...

order by之后的injection(sqllabs第四十六关)
order by相关注入知识 这一关的sql语句是利用的order by 根据输入的id不同数据排序不一样可以确定就是order by order by后面无法使用ubion注入(靠找不到) 可以利用后面的参数进行攻击 1)数字 没作用考虑布尔类型 rand和select ***都可以 …...
C++ 树与图的广度优先遍历 || 模版题 :图中点的层次
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。 所有边的长度都是 1 ,点的编号为 1∼n 。 请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1 。 输入格式 第一行包含两个整数 n 和 m 。 …...

k8s---pod控制器
pod控制器发的概念: 工作负载,workload用于管理pod的中间层,确保pod资源符合预期的状态。 预期状态: 1、副本数 2、容器重启策略 3、镜像拉取策略 pod出故障的出去等等 pod控制器的类型: 1、replicaset…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...