统一返回响应
前言
我们为什么要设置统一返回响应
-
提高代码的可维护性:通过统一返回请求的格式,可以使代码更加清晰和易于维护,减少重复的代码,提高代码质量。
-
便于调试和测试:统一的返回格式使得在调试和测试时更为简单,可以快速定位和解决问题。
-
增强系统的可靠性:统一的返回格式有助于保证系统的稳定性和一致性,减少因不同模块返回格式不统一而导致的错误。
-
提升用户体验:统一的返回格式使得前端处理更加便捷,提高了响应速度,提升了用户体验。
-
便于日志记录和监控:统一的返回格式便于记录和监控系统的运行状态,方便进行故障排查和性能优化。
-
简化前后端接口对接:前后端约定统一的返回格式后,接口对接工作会变得更加顺畅,减少沟通成本和开发时间。
-
提高扩展性:统一的返回格式有利于系统扩展,当需要新增功能或模块时,只需遵循既定的返回格式,无需大规模修改已有代码。
-
保证数据安全:通过统一的返回格式,可以更好地控制返回的数据内容,避免敏感信息的泄露,提高数据安全性。
确定响应实体
我们首先要定义一个公共的接口响应实体,以后所有的接口返回值,都是返回的这个公共响应实体。
这样做的好处是可以统一返回值的风格,编译接口的维护。
需要包含3个关键的成员变量:
- 状态码
- 返回信息
- 数据
/*** api请求响应实体** @author * @date */
@AllArgsConstructor
@Data
public class ApiResult<T> {/*** 请求成功状态码*/public static final int OK = HttpStatus.HTTP_OK;/*** 接口返回码*/private int code;/*** 接口返回信息*/private String message;/*** 数据*/private T data;
}
确定响应实体工具类
为了更加优雅的创建相应实体类,我们可以增加一个专门的工具类。
这个工具类的职责是创建上面的ApiResult类的实例。
当然有两种情况:
/*** api请求响应实体处理工具类**/
public class ApiResultUtil {private ApiResultUtil() {}/*** 请求成功** @param data 数据* @param <T> 数据类型* @return 接口相应实体*/public static <T> ApiResult<T> success(T data) {return new ApiResult<>(ApiResult.OK, null, data);}/*** 请求成功** @param <T> 数据类型* @return 接口相应实体*/public static <T> ApiResult<T> success() {return success(null);}/*** 请求成功** @param code 返回码* @param message 返回信息* @param <T> 数据类型* @return 接口相应实体*/public static <T> ApiResult<T> error(int code, String message) {return new ApiResult<>(code, message, null);}
}
ApiResultUtil工具类中包含了两个重载的success方法,主要是处理接口请求成功的情况。
而error方法,主要是为了处理接口请求出现异常的情况。
需要注意的是ApiResultUtil类有一个私有的无参构造方法,是为了防止调用者new这个类的实例对象的一种常规做法,很多JDK源码中都有类似的做法。
业务异常
有了上面公共的响应实体类,我们可以先处理异常了。
但异常有两种:
- 系统异常
- 业务异常
系统异常我们在统一处理时,错误码都返回500没问题。
但如果有些业务异常,错误码都返回500,这种设计不太合理。
因此,我们需要增加一个专门的业务异常类:BusinessException。
AllArgsConstructor
@Data
public class BusinessException extends RuntimeException {public static final long serialVersionUID = -6735897190745766939L;/*** 异常码*/private int code;/*** 具体异常信息*/private String message;public BusinessException() {super();}
}
这个异常类继承了RuntimeException类,是一种运行时异常,后面好处理。
包含了两个成员变量:
- code:表示异常码
- message:表示异常信息
比如用户添加接口中,出现用户名称相同时,异常信息可以提示:用户名称重复。
全局异常处理
接下来,我们可以统一处理全局异常了。
在Spring MVC中可以通过@RestControllerAdvice注解处理全局异常:
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 统一处理异常** @param e 异常* @return API请求响应实体*/@ExceptionHandler(Throwable.class)public ApiResult handleException(Throwable e) {if (e instanceof BusinessException) {BusinessException businessException = (BusinessException) e;log.info("请求出现业务异常:", e);return ApiResultUtil.error(businessException.getCode(), businessException.getMessage());}log.error("请求出现系统异常:", e);return ApiResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误");}
}
正常接口响应处理
@ControllerAdvice
public class GlobalApiResultHandler implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = sra.getRequest();String requestURI = request.getRequestURI();return matchUrl(requestURI);}private boolean matchUrl(String uri) {if (StringUtils.isBlank(uri)) {return false;}return uri.contains("/v1");}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof ApiResult) {return (ApiResult) body;}return ApiResultUtil.success(body);}
}
相关文章:
统一返回响应
前言 我们为什么要设置统一返回响应 提高代码的可维护性:通过统一返回请求的格式,可以使代码更加清晰和易于维护,减少重复的代码,提高代码质量。 便于调试和测试:统一的返回格式使得在调试和测试时更为简单ÿ…...

大数据学习问题记录
问题记录 node1突然无法连接finalshell node1突然无法连接finalshell 今天我打开虚拟机和finalshell的时候,发现我的node1连接不上finalshell,但是node2、node3依旧可以链接,我在网上找了很多方法,但是是关于全部虚拟机连接不上finalshell&a…...

第N4周:中文文本分类
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 一、预备知识 中文文本分类和英文文本分类都是文本分类,为什么要单独拎出来个中文文本分类呢? 在自然语言处理(NLP&#x…...

【kubernetes】探索k8s集群的pod控制器详解(Deployment、StatefulSet、DaemonSet、Job、CronJob)
目录 一、Pod控制器及其功用 二、pod控制器有多种类型 2.1ReplicaSet 2.1.1ReplicaSet主要三个组件组成 2.2Deployment 2.3DaemonSet 2.4StatefulSet 2.5Job 2.6Cronjob 三、Pod与控制器之间的关系 3.1Deployment 3.2SatefulSet 3.2.1StatefulSet三个组件 3.2.2为…...
直接插入排序
#include <stdio.h>void insert_sort(int arr[], int n) {int i;int j;int tmp;for (i 1; i < n; i){tmp arr[i];j i - 1;// 将要插入的元素与数组中的元素比较(从后向前比) while (j > 0 && arr[j] > tmp){arr[j 1] arr[…...
esp32s3 nvs 存储过程中使用malloc和free函数的一点困惑
我的项目中,大量使用了malloc()和free()函数,在使用nvs存储之前没有出现问题。 esp32厂家nvs的blob存储的例程中,有使用malloc()和free(),我参照例程写了自己的blob存储函数f,一开始是可以正常使用的,后来…...
除visio以外的几款好用流程图绘制工具
流程图绘制软件在嵌入式软件开发中扮演着重要的角色,它们能够帮助用户清晰、直观地展示工作流程。以下是几款流行的流程图绘制软件及其特点的详细报告: 思维导图MindMaster MindMaster作为一款专业的思维导图软件,不仅具备强大的思维导图制作…...
CentOS 7 64位 常用命令
一、系统管理命令 systemctl start firewalld.service:启动防火墙服务 systemctl stop firewalld.service:停止防火墙服务 systemctl enable firewalld.service:设置防火墙服务开机自启 systemctl disable firewalld.service:禁止…...

ChatGPT-4o抢先体验
速度很快,结果很智能,支持多模态输入输出,感兴趣联系作者。 windows/linux/mac 客户端下载参考:https://github.com/lencx/Noi...

STM32实验之USART串口发送+接受数据(二进制/HEX/文本)
涉及三个实验: 1.USART串口发送和接收数据 我们使用的是将串口封装成为一个Serial.c模块.其中包含了 void Serial_Init(void);//串口初始化 void Serial_SendByte(uint8_t Byte);//串口发送一个字节 void Serial_SendArray(uint8_t *Array,uint16_t Length);//…...

网关(Gateway)- 内置过滤器工厂
官方文档:Spring Cloud Gateway 内置过滤器工厂 AddRequestHeaderGatewayFilterFactory 为请求添加Header Header的名称及值 配置说明 server:port: 8088 spring:application:name: api-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8847username: nacos…...

电风扇如何实现跌倒断电保护功能
电风扇作为日常生活中常用的家电产品,为了提升安全性能,在设计上通常会考虑加入跌倒断电保护功能。其中,光电倾倒开关是实现跌倒断电保护功能的关键组件之一。 光电倾倒开关内置红外发光二极管和光敏接收器,其工作原理非常巧妙。…...

编译原理总结
编译器构成 1. 前端分析部分 1.1 词法分析 确定词性,输出为token序列 1.2 语法分析 识别短语 1.3 语义分析 分析短语在句子中的成分 IR中间代码生成 2. 机器无关代码优化 3. 后端综合部分 目标代码生成 机器相关代码优化 4. 其他 全局信息表 异常输出...
JavaScript:从基础到进阶的全面介绍
JavaScript:从基础到进阶的全面介绍 JavaScript(简称JS)是一种广泛用于Web开发的编程语言。它是一种轻量级的、解释型或即时编译的语言,具有函数优先的特点。JS最初是为了实现网页的动态效果而设计的,如今已发展成为前…...
linux指令-sed
sed 是一个流编辑器,用于对输入流(或文件)进行基本的文本转换。以下是 sed 命令的详细输出说明文档: 1. 基本语法 sed [OPTIONS]... [SCRIPT] [INPUTFILE...] OPTIONS:可选的命令行选项,如 -i 用于直接修…...

Docker部署青龙面板
青龙面板 文章目录 青龙面板介绍资源列表基础环境一、安装Docker二、安装Docker-Compose三、安装青龙面板3.1、拉取青龙(whyour/qinglong)镜像3.2、编写docker-compose文件3.3、检查语法启动容器 四、访问青龙面板五、映射本地部署的青龙面板至公网5.1、…...

【LeetCode】每日一题 2024_6_4 将元素分配到两个数组中 II(二分、离散化、树状数组)
文章目录 LeetCode?启动!!!题目:将元素分配到两个数组中 II题目描述代码与解题思路 每天进步一点点 LeetCode?启动!!! 又有段时间没写每日一题的分享了,原本今…...

JAVA小案例-break练习,随机数,到88停止
JAVA小案例-break练习,随机数,到88停止 代码如下: public class Break {/*** break练习,随机数,到88停止* param args*/public static void main(String[] args) {int count0;//计数器System.out.println("Begi…...

C++第三方库【httplib】断点续传
什么是断点续传 上图是我们平时在浏览器下载文件的场景,下载的本质是数据的传输。当出现网络异常,浏览器异常,或者文件源的服务器异常,下载都可能会终止。而当异常解除后,重新下载文件,我们希望从上一次下载…...

[SaaS] AI+数据,tiktok选品,找达人,看广告数据
TK观察专访丨前阿里“鲁班”创始人用AIGC赋能TikTok获千万融资用AI数据做TikTokhttps://mp.weixin.qq.com/s/xp5UM3ROo48DK4jS9UBMuQ主要还是爬虫做数据的。 商家做内容:1.找达人拍内容,2.商家自己做原生自制内容,3.广告内容。 短视频&…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...