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 社会转变:新时代的黎明 曾几何时,不久前…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
