统一返回响应
前言
我们为什么要设置统一返回响应
-
提高代码的可维护性:通过统一返回请求的格式,可以使代码更加清晰和易于维护,减少重复的代码,提高代码质量。
-
便于调试和测试:统一的返回格式使得在调试和测试时更为简单,可以快速定位和解决问题。
-
增强系统的可靠性:统一的返回格式有助于保证系统的稳定性和一致性,减少因不同模块返回格式不统一而导致的错误。
-
提升用户体验:统一的返回格式使得前端处理更加便捷,提高了响应速度,提升了用户体验。
-
便于日志记录和监控:统一的返回格式便于记录和监控系统的运行状态,方便进行故障排查和性能优化。
-
简化前后端接口对接:前后端约定统一的返回格式后,接口对接工作会变得更加顺畅,减少沟通成本和开发时间。
-
提高扩展性:统一的返回格式有利于系统扩展,当需要新增功能或模块时,只需遵循既定的返回格式,无需大规模修改已有代码。
-
保证数据安全:通过统一的返回格式,可以更好地控制返回的数据内容,避免敏感信息的泄露,提高数据安全性。
确定响应实体
我们首先要定义一个公共的接口响应实体,以后所有的接口返回值,都是返回的这个公共响应实体。
这样做的好处是可以统一返回值的风格,编译接口的维护。
需要包含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.广告内容。 短视频&…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
