SpringBoot统一功能处理——统一数据返回格式
目录
一、简单使用
二、存在的问题描述
三、优点
一、简单使用
统一的数据返回格式使用 @ControllerAdvice 和 ResponseBodyAdvice 的方式实现 @ControllerAdvice 表示控制器通知类。
添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接口,并在类上添加 @ControllerAdvice 注解。
import com.example.demo.model.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import
org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest
request, ServerHttpResponse response) {return Result.success(body);}
}
supports方法: 判断是否要执行beforeBodyWrite方法。true为执行,false不执行。 通过该方法可以选择哪些类或哪些方法的response要进行处理, 其他的不进行处理。
//获取执行的类
Class<?> declaringClass = returnType.getMethod().getDeclaringClass();
//获取执行的方法
Method method = returnType.getMethod(); beforeBodyWrite方法: 对response方法进行具体操作处理。
二、存在的问题描述
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- SourceHttpMessageConverter
- SourceHttpMessageConverter
- AllEncompassingFormHttpMessageConverter
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapterimplements BeanFactoryAware, InitializingBean {//...public RequestMappingHandlerAdapter() {this.messageConverters = new ArrayList<>(4);this.messageConverters.add(new ByteArrayHttpMessageConverter());this.messageConverters.add(new StringHttpMessageConverter());if (!shouldIgnoreXml) {try {this.messageConverters.add(new SourceHttpMessageConverter<>());}catch (Error err) {// Ignore when no TransformerFactory implementation is available}}this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());}//...
} public AllEncompassingFormHttpMessageConverter() {if (!shouldIgnoreXml) {try {addPartConverter(new SourceHttpMessageConverter<>());}catch (Error err) {// Ignore when no TransformerFactory implementation is available}if (jaxb2Present && !jackson2XmlPresent) {addPartConverter(new Jaxb2RootElementHttpMessageConverter());}}if (kotlinSerializationJsonPresent) {addPartConverter(new KotlinSerializationJsonHttpMessageConverter());}if (jackson2Present) {addPartConverter(new MappingJackson2HttpMessageConverter());}else if (gsonPresent) {addPartConverter(new GsonHttpMessageConverter());}else if (jsonbPresent) {addPartConverter(new JsonbHttpMessageConverter());}if (jackson2XmlPresent && !shouldIgnoreXml) {addPartConverter(new MappingJackson2XmlHttpMessageConverter());}if (jackson2SmilePresent) {addPartConverter(new MappingJackson2SmileHttpMessageConverter());}
}
- 当返回的数据是非字符串时, 使用的 MappingJackson2HttpMessageConverter 写入返回对象。
- 当返回的数据是字符串时,StringHttpMessageConverter 会先被遍历到,这时会认为 StringHttpMessageConverter 可以使用。
public abstract class AbstractMessageConverterMethodProcessor extends
AbstractMessageConverterMethodArgumentResolver
implements HandlerMethodReturnValueHandler {//...代码省略
protected <T> void writeWithMessageConverters(@Nullable T value,
MethodParameter returnType,
ServletServerHttpRequest inputMessage, ServletServerHttpResponse
outputMessage)
throws IOException, HttpMediaTypeNotAcceptableException,
HttpMessageNotWritableException {//...代码省略
if (selectedMediaType != null) {
selectedMediaType = selectedMediaType.removeQualityValue();
for (HttpMessageConverter<?> converter : this.messageConverters) {
GenericHttpMessageConverter genericConverter = (converter
instanceof GenericHttpMessageConverter ?
(GenericHttpMessageConverter<?>) converter : null);
if (genericConverter != null ?
((GenericHttpMessageConverter)
converter).canWrite(targetType, valueType, selectedMediaType) :
converter.canWrite(valueType, selectedMediaType)) {//getAdvice().beforeBodyWrite 执⾏之后, body转换成了Result类型的结果
body = getAdvice().beforeBodyWrite(body, returnType,
selectedMediaType,
(Class<? extends HttpMessageConverter<?>>)
converter.getClass(),
inputMessage, outputMessage);
if (body != null) {
Object theBody = body;
LogFormatUtils.traceDebug(logger, traceOn ->"Writing [" + LogFormatUtils.formatValue(theBody, !traceOn) + "]");
addContentDispositionHeader(inputMessage, outputMessage);if (genericConverter != null) {genericConverter.write(body, targetType,
selectedMediaType, outputMessage);}else {//此时cover为StringHttpMessageConverter((HttpMessageConverter) converter).write(body,
selectedMediaType, outputMessage);}}else {if (logger.isDebugEnabled()) {logger.debug("Nothing to write: null body");}}return;}}}//...代码省略}//...代码省略
}
三、优点
- 方便前端程序员更好的接收和解析后端数据接口返回的数据;
- 降低前端程序员和后端程序员的沟通成本, 按照某个格式实现就可以了, 因为所有接口都是这样返回的;
- 有利于项目统一数据的维护和修改;
- 有利于后端技术部门的统一规范的标准制定, 不会出现稀奇古怪的返回内容。
相关文章:
SpringBoot统一功能处理——统一数据返回格式
目录 一、简单使用 二、存在的问题描述 三、优点 一、简单使用 统一的数据返回格式使用 ControllerAdvice 和 ResponseBodyAdvice 的方式实现 ControllerAdvice 表示控制器通知类。 添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接口,并在类上添加 …...
Milvus 实践(2) --- 2.4.x 安装,脚本分析,数据存储解析
目录 背景 Milvus2.4.x安装脚本分析 etcd组件 container_name image 参数 注意问题 environment volumes 实体化 command 参数 注意事项 healthcheck 参数 作用 下载 minio组件 container_name image 参数 注意事项 environment 参数 ports 参数 注…...
【蛋疼c++】千万别用std::wifstream读取Unicode UTF16文件
上当了。 最近程序要和 Jscript / activex 脚本通信。 ActiveX这玩意,导出文件,如果是UTF8导出,会出现莫名异常:写一半直接退出。或许是系统语言设置的问题。 但是切换为utf16(unicode)导出就没有问题&a…...
[算法] 第二集 二叉树中的深度搜索
深度优先遍历(DFS,全称为 Depth First Traversal),是我们树或者图这样的数据结构中常⽤的 ⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分支,直到⼀条路径上的所有节点都被遍历 完毕,然后再回溯到上…...
放弃使用外键时,sequelize 应该怎么使用?
在使用 Sequelize 时,如果想放弃使用外键,但仍然希望在模型之间建立关联,可以通过设置 constraints 选项为 false 来实现。这允许你定义模型之间的关系,而不在数据库中创建外键约束。以下是具体的实现步骤: 定义没有外…...
Microsoft GraphRAG 输出的配置信息
Microsoft GraphRAG 输出的配置信息 {"llm": {"api_key": "REDACTED, length 9","type": "oci_genai_chat","model": "cohere.command-r-plus","max_tokens": 4000,"temperature"…...
怎么判断张量的维度(形状(shape)),即如何定义行数、列数和深度的?
举一个三维张量吧 # 3行4列深度为2 const3 tf.constant([[[1,2],[3,4],[5,6],[7,8]],[[11, 12], [13, 14], [15, 16], [17, 18]],[[21, 22], [23, 24], [25, 26], [27, 28]] ],tf.float16) shape (3,4,2)--借鉴博主奶油松果的图和代码 分析形状 (3, 4, 2) 最外层的括号&…...
AI入门指南(二):算法、训练、模型、大模型是什么?
文章目录 一、前言二、算法是什么?概念实际应用 三、训练是什么?概念实际应用 四、模型是什么?概念实际应用小结 五、大模型是什么?概念大模型和小模型有什么区别?大模型分类实际应用 六、总结七、参考资料 一、前言 …...
CSS已访问链接的隐私保护
摘抄自:《CSS权威指南 第四版》 有超过十年的时间,已访问的链接可以使用任何可用的CSS属性装饰,与未访问链接没有差别。 然而,大约在2005年,有几个人通过示例揭露,通过视觉样式和简单的DOM脚本就可以判断用…...
代码练习12-排序链表
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 归并排序算法核心步骤 归并排序核心步骤如下: 把长度为n的要排序的序列,分成两个长度为n/2的子序列;对这两个子序列,分别采用归并排序;…...
Linux 内核源码分析---套接字
套接字通信 ISO 设计一种参考模型,定义组成网络的各个层,该模型由7层组成,称为OSI(开放 系统互连)模型如下: 应用层:网络服务与最终用户的接口; 表示层:数据的表示、安…...
vscode配置xdebug断点调试详细教程
注:环境为本地windows开发环境,编辑器为vscode,PHP集成环境工具为EServer vscode安装扩展并配置 安装PHP Debug 扩展中搜索 PHP Debug 并安装: 配置PHP Debug 1、点击扩展设置 2、在设置中,点击 setting.json 3、编…...
【人工智能】Transformers之Pipeline(八):文生图/图生图(text-to-image/image-to-image)
目录 一、引言 二、文生图/图生图(text-to-image/image-to-image) 2.1 文生图 2.2 图生图 2.3 技术原理 2.3.1 Diffusion扩散模型原理 2.3.2 Stable Diffusion扩散模型原理 2.4 文生图实战 2.4.1 SDXL 1.0 2.4.2 SD 2.0 2.5 模型排名 三、总…...
AI Agent 工程师认证-学习笔记(1)——【单Agent】ModelScope-Agent
学习链接: 【单Agent】ModelScope-Agent学习指南https://datawhaler.feishu.cn/wiki/GhOLwvAPkiSWmokjUgqc1eGonDf 手把手Agent开发开源教程(觉得不错的话可以star一下)https://github.com/datawhalechina/agent-tutorial 动手学Agent应用…...
【Python机器学习】树回归——将CART算法用于回归
要对数据的复杂关系建模,可以借用树结构来帮助切分数据,如何实现数据的切分?怎样才能知道是否已经充分切分?这些问题的答案取决于叶节点的建模方式。回归树假设叶节点是常数值,这种策略认为数据中的复杂关系可以用树结…...
前端(HTML + CSS)小兔鲜儿项目(仿)
前言 这是一个简单的商城网站,代码部分为HTML CSS 和少量JS代码 项目总览 一、头部区域 头部的 购物车 和 手机 用的是 文字图标,所以效果可以和文字一样 购物车右上角用的是绝对定位 logo用的是 h1 标签,用来提高网站搜索排名 二、banne…...
【Rust光年纪】构建高效终端用户界面:Rust库全面解析
构建优雅终端应用:深度评析六大Rust库 前言 随着Rust语言的流行和应用场景的不断扩大,对于终端操作和用户界面构建的需求也日益增长。本文将介绍一些在Rust语言中常用的终端操作库和用户界面构建库,以及它们的核心功能、使用场景、安装与配…...
鼠标滑动选中表格部分数据列(vue指令)
文章目录 代码指令代码使用代码 代码 指令代码 // 获得鼠标移动的范围 function getMoveRange(startClientX, endClientX, startClientY, endClientY) {const _startClientX Math.min(startClientX, endClientX);const _endClientX Math.max(startClientX, endClientX);con…...
“5G+Windows”推动全场景数字化升级:美格智能5G智能模组SRM930成功运行Windows 11系统
操作系统作为连接用户与数字世界的桥梁,在数字化迅速发展的时代扮演着至关重要的角色,智能设备与操作系统的协同工作,成为推动现代生活和商业效率的关键力量。其中,Windows系统以其广泛的应用基础和强大的兼容性成为全球最广泛使用…...
c语言学习,isupper()函数分析
1:isupper() 函数说明: 检查参数c,是否为大写英文字母。 2:函数原型: int isupper(int c) 3:函数参数: 参数c,为检测整数 4:返回值: 参数c是大写英文字母&…...
基于yolov8的路面缺陷检测系统
一、项目介绍 在城市化进程不断加速的大背景下,道路安全与维护的重要性日益凸显。传统人工巡检路面缺陷的方式,因其效率较低、主观性较强等问题,逐渐难以满足当下道路管理的实际需求。YOLOv8 算法在目标检测领域展现出了突出的性能࿰…...
数字化转型深水区:技术从“支撑”到“驱动”的蜕变
对于身处一线的软件测试从业者而言,“数字化转型”早已不是一个陌生的词汇。我们经历了从手工测试到自动化测试的转变,见证了敏捷与DevOps带来的流程革新。然而,当转型浪潮进入“深水区”,一种更为根本的变革正在发生:…...
5款轻量级效率工具让你的文字识别效率提升300%:Umi-OCR完全指南
5款轻量级效率工具让你的文字识别效率提升300%:Umi-OCR完全指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内…...
别再死记硬背了!用‘减法’和‘host/any’关键字,5分钟搞定思科ACL通配符掩码配置
思科ACL通配符掩码:5分钟掌握减法计算与host/any实战技巧 刚接触思科ACL配置时,通配符掩码总是让人头疼。那些0和1的组合看似简单,实际配置时却容易出错。但你可能不知道,掌握两个核心技巧就能彻底解决这个问题——用255.255.255.…...
KMS_VL_ALL_AIO:Windows和Office智能激活的革命性解决方案
KMS_VL_ALL_AIO:Windows和Office智能激活的革命性解决方案 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows和Office激活问题烦恼吗?KMS_VL_ALL_AIO是一款创…...
别再纠结FP32了!手把手教你用PyTorch的BF16和FP16加速大模型训练(附完整代码)
突破显存瓶颈:PyTorch混合精度训练实战指南 当你在深夜盯着屏幕上那个"CUDA out of memory"的错误提示时,是否感到一阵无力?大模型训练就像是在走钢丝——一边是宝贵的显存资源,另一边是模型性能的悬崖。作为一名经历过…...
效率倍增:借助快马ai智能生成与管理系统化java面试题库
作为一名经常需要准备Java面试的开发者,我深刻体会到传统刷题方式的低效——手动收集题目、整理答案、标注重点不仅耗时,还容易遗漏关键知识点。最近尝试用InsCode(快马)平台的AI功能搭建了一个智能题库工具,效率提升超乎想象。以下是具体实现…...
Python量化交易系统:专业回测与组合优化
先把最重要的前提说清楚:国内禁止未经许可的程序化自动交易,下面只做量化研究、回测、信号分析,不含实盘自动下单这套是专业完整版量化系统,Python 可直接运行,结构完整、可扩展包含你要的所有高级功能:多股…...
别再乱选格式了!LVGL图片转换工具(lv_img_conv)保姆级使用指南,从BMP到C数组一次搞定
LVGL图像转换实战指南:从格式选择到批量处理的完整解决方案 在嵌入式UI开发中,图像资源处理往往是第一个技术门槛。许多开发者在使用LVGL时,80%的初期问题都集中在图像转换环节——为什么转换后的图片显示异常?如何平衡内存占用和…...
OpenClaw技能共享:将自研的Phi-3-vision-128k-instruct图表分析模块发布到ClawHub
OpenClaw技能共享:将自研的Phi-3-vision-128k-instruct图表分析模块发布到ClawHub 1. 为什么需要共享技能 去年我在处理一批市场分析报告时,发现手动从PDF中提取图表数据再制作可视化报表的效率极低。当时用OpenClawPhi-3-vision模型搭建了一个自动化分…...
