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是大写英文字母&…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
