SpringMvc 与 Lombok 碰撞导致 JSON 反序列化失败
SpringMvc 与 Lombok 中 JSON 反序列化失败
错误复现_1
@Data
public class User{private Long id;private boolean isOk;
}@RequestMapping
public R<User> getUser(@RequestBody User user){return R.success(user);
}// 前端传参 - {"id": 123456789,"isOk": true}
// 后端返回 - {"id": 123456789,"isOk": false}
排查分析_1
查看 User 类 class 文件。
public class User{pirvate Long id;private boolean isOk;public User() {}public Long getId() { return this.id; }public boolean isOk() { return this.isOk; }public void setId(final Long id) { this.id = id; }public void setOk(final boolean isOk) { this.isOk = isOk; } }提出猜测:Lombok 对于 boolean 类型生成的 Getter/Setter 方法与其他类型不同,该原因导致的数据不一致。
错误复现_2
@Data
public class User{private Long id;private String Name;private Long cId;
}// 前端传参 - {"id": 1,"Name": "LXL","cId": 2}@RequestMapping
public void getUser(@RequestBody User user){System.out.println(user.getId()); // 1System.out.println(user.getName()); // nullSystem.out.println(user.getCId()); // null
}
排查分析_2
查看 User 类 class 文件。
public class User {private Long id;private String Name;private Long cId;public User() {}public Long getId() { return this.id; }public String getName() { return this.Name; }public Long getCId() { return this.cId; }public void setId(final Long id) { this.id = id; }public void setName(final String Name) { this.Name = Name; }public void setCId(final Long cId) { this.cId = cId; } }提出猜测:反序列化时,由于某种原因导致无法正常赋值。
揭开谜团
结合上述两个猜测,去了解了 SpringMvc 的反序列化机制、Lombok 的代码生成机制。
先说一下 SpringMvc 的 @RequestBody 注解:
- SpringMvc 中通过 @RequestBody 注解实现将 json 数据转成 java 对象。
- 处理 @RequestBody 注解时,内部使用 jackson 框架完成该反序列化过程。
接下来是 Jackson 框架的反序列化操作步骤:
- 仅有全参数构造器时,通过调用该构造器,映射 JSON 属性与 Construction 参数列表完成对象的实例化。
- 有无参数构造器时,优先使用无参数构造器 + Getter/Setter 方法完成序列化与反序列化。调用反序列化的目标类的无参构造函数,构造一个 java 对象。然后调用该类的成员变量的 set 方法,为该对象的每一个成员变量赋值。
- Jackson 遵守了
JavaBean的规范:
- 首字母为大写的属性名(如:Name, URL, SuV…),这种属性名直接忽略不注入。
- 第一个字母是小写,第二个字母大写的情况(如:pId, sUV…),在生成 Getter/Setter 的时,直接在前面加上 set/get,比如 pId 生成 setpId()/getpId(),所以 pId 属性在注入的时候会寻找 setpId() 方法,而不是 setPId() 。
最后是 Lombok 的 Getter/Setter 生成机制:
- 当成员变量为 boolean 类型时,属性名为 isXxx 生成的 Getter/Setter 方法的方法名为 isXxx/setXxx。
- 其他基本类型与所有引用数据类型,属性名为 aaBb 生成的 Getter/Setter 方法的方法名为 getAaBb/setAaBb,例如 isXxx 生成 getIsXxx/SetIsXxx。
这几个知识点就可以解决错误 1、错误 2 啦!!!
- 错误 1 造成原因:为属性名 isOk 查找 Setter 方法时,找不到 setIsOk,所以无法注入,使用默认值 false。
- 错误 2 造成原因:属性名 Name 不符合 JavaBean 规范被直接忽略注入;属性名 cId 查找的 Setter 方法名应该为 setcId,而 Lombok 生成的是 setCId,也是注入不了的。
方案与总结
- 规范且合理制定成员变量名称。
- 尽量使用包装类,既可以符合 Java 语言面向对象的特性,同时可以避免 Lombok 生成的 Setter/Getter 与 Jackson 框架规则间的冲突。
- 上述两种方案不适合的话,可以考虑手动生成 Setter/Getter 方法。
- 通过 @JsonProperty 显式指定 JSON 属性与 Java 属性的对应关系。
相关文章:
SpringMvc 与 Lombok 碰撞导致 JSON 反序列化失败
SpringMvc 与 Lombok 中 JSON 反序列化失败 错误复现_1 Data public class User{private Long id;private boolean isOk; }RequestMapping public R<User> getUser(RequestBody User user){return R.success(user); }// 前端传参 - {"id": 123456789,"i…...
怎么样显卡叠加,什么是NVIDIA 显卡 非公、公版、涡轮卡
1、显存叠加的问题,因为这个跟是否是深度学习无关: 先说一下显存叠加的问题,因为这个跟是否是深度学习无关:一台机器有多张显卡,显存不会叠加!显卡里面包含了显存、cache、计算单元、通信等,每…...
CentOS安装Elasticsearch集群
前言 之前使用的ES集群是其他公司维护,没有机会安装,后来做其他项目,终于有机会安装ES集群,简单记录一下备用 一、安装jdk 安装jdk1.8就可以,可以参考另一篇文章,这里就不细说了 二、修改系统参数 如果在…...
计算机专业毕业生指南
在大四毕业时,完成计算机毕业设计需要一定的计划和组织。以下是一些建议,帮助你在三个月内快速完成毕业设计: 选择一个合适的主题: 选择一个你感兴趣的主题,这将激发你的热情,使你更有动力完成项目。 确保…...
Springboot集成Docker并将镜像推送linux服务器
案例使用springboot项目,在IDEA 中集成Docker生成镜像,并将镜像发布到linux服务器 具体步骤如下: 1、Centos7安装Docker 更新系统的软件包列表 sudo yum update安装Docker所需的软件包和依赖项: sudo yum install docker完成…...
数字孪生与GIS:智慧城市的未来之路
数字孪生和地理信息系统(GIS)是两个在现代科技中崭露头角的概念,它们的融合为智慧城市项目带来了革命性的机会。本文将解释数字孪生为何需要融合GIS,并以智慧城市项目为例进行说明。 数字孪生是一种虚拟模型,它精确地…...
nas汇编程序的调试排错方法
nas汇编程序的调试排错方法: 1、查找是哪一步错了 2、查看对应的*.lst文件,本例中是"asmhead.lst" 3、根据*.lst文件的[ERROR #002]提示查看源码,改错。 4、重新运行编译,OK 1、查找是哪一步错了: nask.ex…...
【网络安全带你练爬虫-100练】第21练:批量获取文件夹中文件名
目录 一、目标1:使用python爬取指定文件夹中的文件名 二、目标2:在文件夹指定目录打开命令行 一、目标1:使用python爬取指定文件夹中的文件名 方法一:使用os模块 将/path/to/folder替换为实际的文件夹路径。os.listdir()函数用…...
Unittest自动化测试框架vs Pytest自动化测试框架
引言 前面一篇文章Python单元测试框架介绍已经介绍了python单元测试框架,大家平时经常使用的是unittest,因为它比较基础,并且可以进行二次开发,如果你的开发水平很高,集成开发自动化测试平台也是可以的。而这篇文章…...
PHP8的数组-PHP8知识详解
今天开始学习数组, 本文主要讲了三点:什么是数组、php8中数组的改进、数组函数。 一、什么是数组 在PHP8中,数组是非常重要的数据类型。相对于其他的数据类型,数组更像一种结构,而这种结构可以储存一系列数值。 数组…...
数据仓库_维度表的两大分类
最近看一篇文章对维度表进行了分类,记录一下。 维度表主要分为两类高基数维度表和低基数维度表。 高基数维度数据 一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。 低基数维度数据 一般是配置表,比如枚举值对应的中文含…...
4、DVWA——文件包含
文章目录 一、文件包含概述二、low2.1 源码分析2.2 通关分析 三、medium3.1 源码分析3.2 通关思路 四、high4.1 源码分析4.2 通关思路 五、impossible 一、文件包含概述 文件包含是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(i…...
产品经理如何进行需求管理
产品经理在进行需求管理时,可以遵循以下步骤: 1. 确定需求目标:明确产品的愿景和目标,确定需求管理的方向和重点。 2. 收集需求:与利益相关者(包括用户、业务部门、技术团队等)沟通,…...
【从0学习Solidity】2. 值类型详解
Solidity极简入门: 2. 值类型 博主简介:不写代码没饭吃,一名全栈领域的创作者,专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构,分享一些项目实战经验以及前沿技术的见解。关注我们的主页,探索全栈开发…...
框架分析(9)-Hibernate
框架分析(9)-Hibernate 专栏介绍Hibernate特性对象关系映射(ORM)数据库连接和事务管理查询语言(HQL)缓存机制透明的持久化操作对象的延迟加载事务管理 优缺点优点简化数据库操作跨数据库平台高度可定制性缓…...
JavaScript中的原型链(prototype chain)
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ JavaScript中的原型链⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚踏…...
设计模式之代理模式与外观模式
目录 代理模式 简介 优缺点 角色职责 实现 运用场景 外观模式 简介 角色职责 优缺点 实现 使用场景 代理模式 简介 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为…...
动手学深度学习(四)多层感知机
目录 一、多层感知机的从零开始实现 1.1 初始化模型参数 1.2 实现Relu函数 1.3 实现模型 1.4 训练 二、多层感知机的简洁实现 2.1 实现模型 2.2 训练 三、模型选择 3.1 训练误差和泛化误差 3.2 验证数据集和测试数据集 3.3 过拟合和欠拟合 3.4 代码实现 3.4.1 生…...
融云出海:社交泛娱乐出海,「从 0 到 1」最全攻略
9 月 21 日,融云直播课社交泛娱乐出海最短变现路径如何快速实现一款 1V1 视频社交应用? 欢迎点击上方小程序报名~ 本期我们翻到《地图》的实践篇,从赛道/品类选择、目标地区适配、用户增长、变现模式、本地化运营、跨国团队管理等方面完整描绘…...
生成式人工智能促使社会转变
作者:JEFF VESTAL 了解 Elastic 如何处于大型语言模型革命的最前沿 – 通过提供实时信息并将 LLM 集成到数据分析的搜索、可观察性和安全系统中,帮助用户将 LLM 提升到新的高度。 iPhone 社会转变:新时代的黎明 曾几何时,不久前…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
