Jackson @JsonUnwrapped注解扁平化 序列化反序列化数据
参考资料
- Jackson 2.x 系列【7】注解大全篇三
- @JsonUnwrapped 以扁平的数据结构序列化/反序列化属性
- Jackson扁平化处理对象
目录
- 一. 前期准备
- 1.1 前端
- 1.2 实体类
- 1.3 Controller层
- 二. 扁平化序列反序列化数据
- 2.1 序列化数据
- 2.2 反序列化数据
- 三. 前缀后缀处理属性同名
- 四. Map数据的处理
一. 前期准备
1.1 前端
$(function() {bindEvent();
});function bindEvent() {$("#btn").click(() => {// 准备提交到后端的数据const jsonData = {id: "112",name: "前端来的name",houseId: "前端来的houseId",address: "前端来的address",blogId: "前端来的blogId",blogName: "前端来的blogName"};$.ajax({url: `/test34/get_data`,type: 'POST',data: JSON.stringify(jsonData),contentType: 'application/json;charset=utf-8',success: function (data, status, xhr) {console.log(data);}});});
}
1.2 实体类
import com.fasterxml.jackson.annotation.*;
import lombok.Data;@Data
public class Test34Entity {private String id;private String name;@JsonUnwrappedprivate House house;@JsonUnwrappedprivate BlogTag blogTag;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class House {private String houseId;private String address;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class BlogTag {private String blogId;private String blogName;
}
1.3 Controller层
mport org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;import java.io.IOException;@Controller
@RequestMapping("/test34")
public class Test34Controller {@GetMapping("/init")public ModelAndView init() {ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("test34");return modelAndView;}@PostMapping("/get_data")public ResponseEntity<Test34Entity> getData(@RequestBody Test34Entity data) throws IOException {System.out.println(data);Test34Entity entity = new Test34Entity();// 设置基本类型的属性值entity.setId("1355930");entity.setName("贾飞天");// 设置自定义类型(bean)的属性值entity.setHouse(new House("house_id_1", "地球"));entity.setBlogTag(new BlogTag("tag_id_1", "tag_name_1"));return ResponseEntity.ok(entity);}
}
二. 扁平化序列反序列化数据
⏹@JsonUnwrapped注解只能处理Bean类型的数据,List<Bean>和Map<键,Bean>等数据类型是无法处理的。
2.1 序列化数据
- 给需要扁平化处理的Bean添加
@JsonUnwrapped注解 - 需要扁平化处理的Bean还需要有
构造函数,必须有构造函数,否则后台接收数据时会报错。 - 这样前台扁平化提交数据的时候,后台可以用一个类组合多个类的方式接收数据
⏹使用@JsonUnwrapped注解之前
- 前台需要提交如下的数据结构,前台的数据结构层次需要根据后台的Bean结构层次调整
const jsonData = {id: "112",name: "前端来的name",house: {houseId: "前端来的houseId",address: "前端来的address"},blogTag: {blogId: "前端来的blogId",blogName: "前端来的blogName" }
};
- 后台使用的数据结构
@Data
public class Test34Entity {private String id;private String name;private House house;private BlogTag blogTag;
}
⏹使用@JsonUnwrapped注解之后,前台无需根据后台的Bean结构来组装数据,直接扁平化提交即可,对于一些不使用Vue,React框架等前台框架的项目有用,能写起来更简单。
- 前台数据结构
const jsonData = {id: "112",name: "前端来的name",houseId: "前端来的houseId",address: "前端来的address",blogId: "前端来的blogId",blogName: "前端来的blogName"
};
- 后台数据结构
@Data
public class Test34Entity {private String id;private String name;@JsonUnwrappedprivate House house;@JsonUnwrappedprivate BlogTag blogTag;
}
⏹实质上是Jackson 通过@JsonUnwrapped注解将House和BlogTag属性拍扁放到Test34Entity实体类中。右下图可以看到,数据自动完成了封装。

2.2 反序列化数据
⏹不使用@JsonUnwrapped注解,前台的json数据结构和后台的Bean相同。

⏹使用@JsonUnwrapped注解,后台的嵌套的Bean属性被展平后返回给前台。

三. 前缀后缀处理属性同名
😅如下图所示,由于Test34Entity类和组合类的属性名相同,从而导致属性丢失。

⏹可以在@JsonUnwrapped注解上指定前缀或后缀来避免属性重名问题
import com.fasterxml.jackson.annotation.*;
import lombok.Data;@Data
public class Test34Entity {private String id;private String name;@JsonUnwrapped(prefix = "house_", suffix = "_suffix")private House house;@JsonUnwrapped(prefix = "blog_", suffix = "_suffix")private BlogTag blogTag;@Datapublic static class BlogTag {private String id;private String name;}@Datapublic static class House {private String id;private String address;}
}
⏹反映到前端的截图如下所示

四. Map数据的处理
😅@JsonUnwrapped注解原生不支持Map,由下图所示,前台得到的json中,blogTagMap属性依然存在。

⏹将Test34Entity 实体类,进行如下修改
- 使用
@JsonAnySetter,@JsonAnyGetter注解 - addBlogTagMap,getBlogTagMap,setBlogTagMap方法名中的blogTagMap部分和属性名blogTagMap保持一致。
import com.fasterxml.jackson.annotation.*;
import lombok.Data;import java.util.Map;@Data
public class Test34Entity {private String id;private String name;private Map<String, BlogTag> blogTagMap;@JsonAnySetterpublic void addBlogTagMap(String key, BlogTag value) {blogTagMap.put(key, value);}@JsonAnyGetterpublic Map<String, BlogTag> getBlogTagMap() {return blogTagMap;}public void setBlogTagMap(Map<String, BlogTag> blogTagMap) {this.blogTagMap = blogTagMap;}
}
⏹然后在前台查看效果,可以看到外侧的blogTagMap属性名不见了。

相关文章:
Jackson @JsonUnwrapped注解扁平化 序列化反序列化数据
参考资料 Jackson 2.x 系列【7】注解大全篇三JsonUnwrapped 以扁平的数据结构序列化/反序列化属性Jackson扁平化处理对象 目录 一. 前期准备1.1 前端1.2 实体类1.3 Controller层 二. 扁平化序列反序列化数据2.1 序列化数据2.2 反序列化数据 三. 前缀后缀处理属性同名四. Map数…...
日期时间相关的类
分界线jdk8 jdk8之前和之后分别提供了一些日期和时间的类,推荐使用jdk8之后的日期和时间类 Date类型 这是一个jdk8之前的类型,其中有很多方法已经过时了,选取了一些没有过时的API //jdk1.8之前的日期 Date Date date new Date(); // 从1970年…...
微信小程序脚本的执行顺序
在小程序中的脚本执行顺序和浏览器中有所不同。 小程序的执行的入口文件是 app.js 。 并且会根据其中 require 的模块顺序决定文件的运行顺序,代码是一个 app.js 示例。 app.js /* a.js console.log(a.js) */ var a require(./a.js) console.log(app.js)/* b.js co…...
zabbix监控警告
监控概述 对服务的管理,不能仅限于可用性。 还需要服务可以安全、稳定、高效地运行。 监控的目的:早发现、早治疗。 被监控的资源类型: 公开数据:对外开放的,不需要认证即可获取的数据 私有数据:对外不…...
YOLOv9架构图分享
YOLOv9是YOLO (You Only Look Once)系列实时目标检测系统的最新迭代。它建立在以前的版本之上,结合了深度学习技术和架构设计的进步,以在目标检测任务中实现卓越的性能。通过将可编程梯度信息(PGI)概念与广义ELAN (GELAN)架构相结合,YOLOv9在…...
全自动封箱机的工作原理:科技与效率的完美结合
随着科技的不断发展,越来越多的自动化设备走进了我们的日常生活和工业生产中。其中,全自动封箱机作为物流包装领域的重要一环,凭借其高效、精准的工作性能,正逐渐成为提升生产效率、降低劳动成本的得力助手。星派就来与大家深入探…...
【管理咨询宝藏48】AA银行信息科技提升分析报告
本报告首发于公号“管理咨询宝藏”,如需阅读完整版报告内容,请查阅公号“管理咨询宝藏”。 【管理咨询宝藏48】AA银行信息科技提升分析报告 【格式】PPT版本,可编辑 【关键词】战略规划、商业分析、管理咨询 【强烈推荐】这是一套市面上非常…...
循序表实战——基于循序表的通讯录
前言:本篇文章主要是利用顺序表作为底层, 实现一个通讯录。偏向于应用, 对于已经学习过c的友友们可能没有难度了已经。没有学习过c的友友, 如果顺序表不会写, 或者说没有自己实现过, 请移步学习顺序表相关内…...
Java编程规范及最佳实践
文章目录 一、命名规范二、代码风格规范三、注释规范四、推荐的编程实践五、类和接口六、异常处理七、可见性八、并发九、代码复用十、代码组织和模块化十一、Java集合框架十二、输入验证十三、资源管理十四、文档和注释十五、测试和代码质量十六、代码可读性十七、性能优化十八…...
90天玩转Python—07—基础知识篇:Python中运算符详解
90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…...
C语言 位域
C 语言的位域(bit-field)是一种特殊的结构体成员,允许我们按位对成员进行定义,指定其占用的位数。 如果程序的结构中包含多个开关的变量,即变量值为 TRUE/FALSE,如下: struct {unsigned int w…...
【LeetCode热题100】【技巧】颜色分类
题目链接:75. 颜色分类 - 力扣(LeetCode) 只需排序三种,可以记录0和1的个数,然后直接原地赋值 class Solution { public:void sortColors(vector<int> &nums) {int zero 0, one 0;for (auto &num: n…...
笔记本电脑win7 Wireless-AC 7265连不上wifi6
1.背景介绍 旧路由器连接人数有限,老旧,信号不稳定更换了新路由器,如 TL-XDR5430易展版用户电脑连不上新的WIFI网络了,比较着急 核心问题:有效解决笔记本连接wifi上网问题,方法不限 2.环境信息 Windows…...
Linux gcc day5粘滞位
粘滞位 背景:一定时在一个公共目录(root创建)下。进行临时文件的操作 Linux系统中有很多人,我们需要在一个公共目录下,进行临时文件的操作(增删查改) 创建一个根目录下的dir(mytmp…...
单片机按键消抖常用的软硬件方法
一:什么是开关抖动? 当我们按下按钮或拨动开关或微动开关时,两个金属部件会接触以短路电源。但它们不会立即连接,而是金属部件在实际稳定连接之前连接和断开几次。释放按钮时也会发生同样的事情。这会导致误触发或多次触发&#…...
钉钉自建应用-下载excel(h5)
由于不同手机对于文件下载有不同的支持,而且文件路径也不一样,找起来十分的麻烦。所以,最好是找到一个都支持的方法。还好,钉钉官网提供了网盘,我们可把文件保存到钉钉自带的网盘,这样方便查找。 这里需要…...
用二八定律分析零售数据,不就更直观了吗?
20%的商品贡献了80%的销售金额,你会不会想知道这些商品的销售金额、毛利、销售金额累计占比、毛利累计占比,会不会想知道这些商品在各个门店的销售表现?看是否能进一步提高销售金额,提高毛利。这样的报表该怎么做?奥威…...
NetSuite Saved Search-当前库存快照查询报表(二)
之前第一篇文章我们说明了,如何利用Saved Search来制作一个能够显示批次物料与非批次物料的Lot信息以及On Hand在手数量的“当前库存快照查询报表”,但是当用户提出“我们能否再加上批次物料的效期”需求时,我们原有的Saved Search并不能达到…...
【JavaSE】接口 详解(上)
前言 本篇会讲到Java中接口内容,概念和注意点可能比较多,需要耐心多看几遍,我尽可能的使用经典的例子帮助大家理解~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 接口 语法…...
嵌入式C基础——循环队列 ringbuffer 讲解
本期主题: 讲解ARRAY_SIZE的作用以及定义,还有一个踩坑分析 往期链接: 数据结构系列——先进先出队列queue数据结构系列——栈 stackLinux内核链表零长度数组的使用inline的作用嵌入式C基础——ARRAY_SIZE使用以及踩坑分析 目录 1. Ringbuff…...
我自己写的论文为什么被判 AI 率 60%?这款工具帮我降到 5% 通过 985 知网严查
我自己写的论文为什么被判 AI 率 60%?这款工具帮我降到 5% 通过 985 知网严查 我是 211 直博生、毕业论文 100% 自己手写、没用过任何 AI 工具。送学校知网 AIGC 检测——AI 率 60%,学校卡 15% 红线。我整个人懵了——明明没用 AI 写、为什么算法判我 AI…...
网络排障利器netstat:从TCP状态机到实战故障排查
1. 网络排障的“听诊器”:为什么是netstat?在服务器运维、后端开发或者日常处理网络问题的过程中,我们经常会遇到一些让人头疼的场景:服务端口明明启动了,客户端却死活连不上;服务器负载莫名飙升࿰…...
KNN和K-Means选错距离度量?详解闵可夫斯基距离中参数p的实战调优
KNN与K-Means距离度量实战:如何用闵可夫斯基距离参数p提升模型性能 当你在scikit-learn中第一次使用KNN分类器时,可能会注意到一个不起眼的参数p——它默认为2,代表使用欧氏距离。但鲜有人告诉你,这个参数的选择可能让你的模型准确…...
SAP EWM实战:从产品到处理单位,两种库存转移操作保姆级教程
SAP EWM库存转移实战指南:产品与处理单位的精准操作 在仓库管理的日常工作中,库存转移是最基础却最容易出错的环节之一。特别是对于刚接触SAP EWM系统的管理员来说,面对不同形态的物料——散件产品和带包装的处理单位(HU),往往会产…...
探索中医数字化:基于深度学习的舌苔检测项目推荐
探索中医数字化:基于深度学习的舌苔检测项目推荐 【下载地址】基于深度学习的舌苔检测毕设留档 本项目是针对中医领域中舌象分析的一项研究,通过应用深度学习技术来实现自动的舌苔检测。随着人工智能在医疗健康领域的深入发展,利用计算机视觉…...
Maintain Certificate Trust List,把 SAP 出站通信里的证书信任关口管清楚
做 SAP S/4HANA Cloud、SAP BTP ABAP environment 或者混合架构里的出站集成时,有一个问题很容易被业务侧低估,却经常成为接口上线前的最后一道卡点,SAP 系统到底信不信任通信伙伴的服务器证书。OAuth、Basic Authentication、Communication Arrangement、Destination、ODat…...
让经典重生:D2DX如何让《暗黑破坏神2》在现代电脑上流畅运行
让经典重生:D2DX如何让《暗黑破坏神2》在现代电脑上流畅运行 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 还记…...
龙芯2K3000与国产OS在轨道交通AFC系统中的工程实践
1. 项目概述:当国产芯遇上城市动脉每天早晚高峰,地铁站里人头攒动,闸机开合的“嘀嘀”声此起彼伏。你可能没留意,支撑这套庞大自动售检票系统(AFC)稳定运行的“大脑”,正经历一场静默而深刻的变…...
WindowResizer:如何打破Windows窗口尺寸限制,实现桌面布局自由?
WindowResizer:如何打破Windows窗口尺寸限制,实现桌面布局自由? 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 在Windows日常使用中࿰…...
Claude规格说明书生成器:提升大模型任务执行效率的工程化方法
1. 项目概述:一个为Claude模型定制的“规格说明书”生成器如果你和我一样,经常与Anthropic的Claude系列大语言模型打交道,无论是Claude 3 Opus、Sonnet还是Haiku,那你肯定遇到过这样的场景:你有一个复杂的任务…...
