【工作笔记】Lombok版本变化导致的反序列化异常
Lombok版本变化导致的反序列化异常
背景
因为安全性的考虑,最近在梳理旧系统的系统依赖。改动依赖时候还好,毕竟只是换掉不再合作公司的旧依赖,没敢动别的太多东西。不过没多久,测试团队就找来了…
排查问题之第一次跑偏
旧系统有一些这样的接口(下图,),全部提示异常…
看了下日志,入参对象为空…
2024-12-10 10:11:52,679 [http-nio-9011-exec-3] INFO [xxx.PreservationController:2238] [trace=d900fbccc0932d79] - PolicyReinstatementReqVO(com.xxx.web.vo.endorse.PolicyReinstatementReqVO@17ad, ContNo=null, OrderNo=null)
入参对象如下(注意,都是首字母大写的)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PolicyReinstatementReqVO implements Serializable {private static final long serialVersionUID = 6056472621794316031L;private String ContNo;private String OrderNo;
}
第一反应就是反序列化出问题了,于是乎,开始查这旧系统的序列化方式。查到了如下配置:
@Beanpublic HttpMessageConverter responseBodyConverter() {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();List<MediaType> mediaTypeList = new ArrayList<>();mediaTypeList.add(MediaType.APPLICATION_JSON);mediaTypeList.add(MediaType.TEXT_HTML);jackson2HttpMessageConverter.setSupportedMediaTypes(mediaTypeList);return jackson2HttpMessageConverter;}
嗯。。用的Jackson(默认大小写敏感的),那就简单了。。改成如下代码
@Beanpublic HttpMessageConverter responseBodyConverter() {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(new JacksonMapper());List<MediaType> mediaTypeList = new ArrayList<>();mediaTypeList.add(MediaType.APPLICATION_JSON);mediaTypeList.add(MediaType.TEXT_HTML);jackson2HttpMessageConverter.setSupportedMediaTypes(mediaTypeList);return jackson2HttpMessageConverter;}
// 代码有删减
class JacksonMapper extends ObjectMapper {public JacksonMapper() {this.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);}
}
测了下,嗯,问题解决…我果然是个天才~
不过想了下,不对劲
- 我就是改了包依赖…没改代码啊…
- 我这么改看似这个问题解决了…但这种改动在这旧系统会不会引发新问题我也不确定…
- 这旧系统之前是怎么在这看似不合理的情况下正常运行的呢?
所以这么改大概率对但不合适,所以先回滚改动吧…
换个思路排查
- 目前能定位的问题是反序列化时出了问题
- 我的改动就是改了依赖包
综上所属,应该是我改了包依赖之后,导致的问题,而我改依赖包可能导致两个变化。
变化一
删除的三方依赖包有处理序列化的逻辑,我拿咖啡baby看了下源码,完全没有…这里的疑虑排除!
变化二
那就是这里了,错不了,依赖的版本变化导致反序列化出现问题了。
排查问题之第二次跑偏
既然是版本问题,那就查查跟序列化有关的包版本变化有什么变化吧。
旧系统有 jackson、gson、fastjson…
查了老久了,不展开说了(后续的反思也在这里),最后定位跟这些没关系。
Lombok
抓耳挠腮,苦思冥想…没有结果,周会到点了,先开周会去吧…
周会结束重新梳理了下思路:
- 修改依赖导致依赖版本出现了变化
- 依赖版本导致反序列化获取不到属性
- 序列化工具,jackson、fastjson、gson都没问题
那问题是什么呢?抛开序列化工具,无论什么序列化工具都是要回归到对象本身的 getter、setter和 Constructor 的。而我们的这些是通过 Lombok 注解实现的,巧的是,Lombok 的版本也升级了…
先看下前后两个版本的变化吧
// 两个版本的getter、setter是没区别的,但是Constructor有!!!
///新版本:1.18.16public PolicyReinstatementReqVO(final String ContNo, final String OrderNo) {this.ContNo = ContNo;this.OrderNo = OrderNo;}
// 旧版本:1.16.18@ConstructorProperties({"ContNo", "OrderNo"})public PolicyReinstatementReqVO(final String ContNo, final String OrderNo) {this.ContNo = ContNo;this.OrderNo = OrderNo;}
旧版本多了个 @ConstructorProperties,说实话我最开始不知道这个注解是做什么用的…惭愧。于是我先把 Lombok 的版本回退到1.16.18,重新 Run 一下。
ok,问题完美解决。
@ConstructorProperties
- ConstructorProperties 注解是 Java 标准库的一部分。它用于在 Java 的构造函数上,以确保在序列化和反序列化时,构造函数的参数名称和顺序与 JSON 对象中的属性名称和顺序相匹配。并且 @ConstructorProperties 注解的值必须与构造函数参数的顺序相匹配。
- Jackson 库支持 ConstructorProperties 注解。但如果构造函数参数使用了 @JsonProperty 注解,那么 @ConstructorProperties 注解的值可以省略,因为 Jackson 可以直接从 @JsonProperty 注解中获取参数名称。
- 通过使用 @ConstructorProperties 注解,你可以确保 Jackson 在序列化和反序列化时能够正确地处理构造函数参数,从而避免因参数名称不匹配而导致的错误。
反思
好的点 这次处理问题的思路挺好,没有使用自己丰富的想象力天马行空一同胡思乱想,而是一直专注在:(1)问题是什么,(2)是什么变化导致这个问题,这两个点上。
不好的点 处理旧系统之前,虽然没那么多时间完全了解旧系统,但既然要删除三方不安全的依赖,就该提前排查和记录现有的依赖都是什么版本,方便后续的问题追踪。
后续 再研究研究 Spring 以及 Jackson 序列化和反序列化流程吧。这块感觉自己比较熟,但处理问题时又没有那么熟。
相关文章:
【工作笔记】Lombok版本变化导致的反序列化异常
Lombok版本变化导致的反序列化异常 背景 因为安全性的考虑,最近在梳理旧系统的系统依赖。改动依赖时候还好,毕竟只是换掉不再合作公司的旧依赖,没敢动别的太多东西。不过没多久,测试团队就找来了… 排查问题之第一次跑偏 旧系…...
多模态大语言模型 MLLM 部署微调实践
1 MLLM 1.1 什么是 MLLM 多模态大语言模型(MultimodalLargeLanguageModel)是指能够处理和融合多种不同类型数据(如文本、图像、音频、视频等)的大型人工智能模型。这些模型通常基于深度学习技术,能够理解和生成多种模…...
LNMP和Discuz论坛
文章目录 LNMP和Discuz论坛1 LNMP搭建1.1 编译安装nginx服务1.1.1 编译安装1.1.2 添加到系统服务 1.2 编译安装MySQL服务1.2.1 准备工作1.2.2 编辑配置文件1.2.3 设置路径环境变量1.2.4 数据库初始化1.2.5 添加mysqld系统服务1.2.6 修改mysql的登录密码 1.3 编译安装PHP服务1.3…...
Cadence学习笔记 2 PCB封装绘制
基于Cadence 17.4,四层板4路HDMI电路 更多Cadence学习笔记:Cadence学习笔记 1 原理图库绘制 目录 2、PCB封装绘制 2、PCB封装绘制 封装尺寸如下。 用Allegro做PCB封装前,要先做焊盘(Allegro 比AD、PADS多一个步骤:绘制…...
网络安全——防火墙
基本概念 防火墙是一个系统,通过过滤传输数据达到防止未经授权的网络传输侵入私有网络,阻止不必要流量的同时允许必要流量进入。防火墙旨在私有和共有网络间建立一道安全屏障,因为网上总有黑客和恶意攻击入侵私有网络来破坏,防火…...
【CSS in Depth 2 精译_074】第 12 章 CSS 排版与间距概述 + 12.1 间距设置(下):行内元素的间距设置
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 12 章 CSS 排版与间距】 ✔️ 12.1 间距设置 12.1.1 使用 em 还是 px12.1.2 对行高的深入思考12.1.3 行内元素的间距设置 ✔️ 12.2 Web 字体12.3 谷歌字体 文章目…...
短视频矩阵抖音SEO源码OEM独立部署
短视频优化矩阵源码涉及对抖音平台上的视频内容进行筛选与排序,目的是增强其在搜索引擎中的可见度,以便更多用户能够浏览到这些视频。而抖音SEO优化系统则是通过构建一个分析框架,来解析抖音上的用户数据、视频信息及标签等元素,并…...
使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像
文章目录 应用快速部署NginxRedisMySQLTomcat 制作镜像镜像原理基于已有容器创建使用 Dockerfile 创建镜像指令说明构建应用创建 Dockerfile 文件创建镜像 应用快速部署 Nginx docker run -d -p 80:80 nginx使用浏览器访问虚拟机地址 Redis docker pull redis docker run --…...
在ensp中ACL路由控制实验
一、实验目的 掌握ACL路由控制管理 二、实验要求 要求: 配置路由策略,左右两边不公开区域对方不可达,其他区域可以互相ping通 设备: 1、三台路由器 2、四台交换机 3、四台电脑 4、四台服务器 使用ensp搭建实验环境,如图所…...
μC/OS-Ⅱ源码学习(3)---事件模型
快速回顾 μC/OS-Ⅱ中的多任务 μC/OS-Ⅱ源码学习(1)---多任务系统的实现 μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下) 本文开始,进入事件源码的学习。 事件模型 在一个多任务系统里,各个任务在系统的统筹下相继执行,由于执行速度极快&a…...
Jmeter进阶篇(30)深入探索 JMeter 监听器
前言 在性能测试领域里,Apache JMeter 是一款经典而强大的工具,而其中的监听器(Listeners)组件更是发挥着不可或缺的关键作用。 监听器就像敏锐的观察者,默默记录测试执行过程中的各种数据,作为系统性能分析的数据依据。 本文将带你全方位走进 JMeter 监听器的奇妙世界,…...
虚幻引擎的工程目录结构
虚幻引擎的工程目录结构如下: .idea/.vs:用于IDE(如IntelliJ IDEA或Visual Studio)的项目配置文件,包含工程设置和解决方案文件。 Binaries:存放编译后的可执行文件和相关的动态链接库(DLL&…...
深度学习中的yield
以下为例: def data_iter(batch_size, features, labels):num_examples len(features)indices list(range(num_examples))# 这些样本是随机读取的,没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices …...
数据库数据恢复—ORACLE常见故障有哪些?如何恢复数据?
Oracle数据库常见故障表现: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。 Oracle数据库数据恢复方案: 1、检测存放数据库的服务器/存储设备是否存…...
使用JavaScrip和HTML搭建一个简单的博客网站系统
搭建一个简单的博客网站系统,我们需要创建几个基本的页面和功能:登录、注册、文章发布等。这里我们先实现一个基础版本,包括用户登录、注册以及文章发布的功能。由于这是一个简化版的示例,我们将所有逻辑集成在一个HTML文件中&…...
算法-字符串-76.最小覆盖子串
一、题目 二、思路解析 1.思路: 滑动窗口!!! 2.常用方法: 无 3.核心逻辑: 1.特殊情况:s或t是否为空字符串 if(snull||tnull)return ""; 2.声明一个字符数组——用于记录对应字符出现…...
Python爬虫之Selenium的应用
【1】Selenium基础介绍 1.什么是selenium? (1)Selenium是一个用于Web应用程序测试的工具。 (2)Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。 (3)支持通过各种driv…...
粉丝生产力与开源 AI 智能名片 2+1 链动模式商城小程序的融合创新与价值拓展
摘要:本文聚焦于粉丝生产力在当代文化与商业语境中的独特作用,并深入探讨其与开源 AI 智能名片 21 链动模式商城小程序的有机结合。通过剖析粉丝生产力的多元表现形式、内在驱动机制以及开源 AI 智能名片 21 链动模式商城小程序的功能特性与商业潜力&…...
红黑树(Red-Black Tree)
一、概念 红黑树(Red Black Tree)是一种自平衡的二叉搜索树,通过添加颜色信息来确保在进行插入和删除操作时,树的高度保持在对数级别,从而保证了查找、插入和删除操作的时间复杂度为 O(log n)。这种树可以很好地解决普…...
Cocos 资源加载(以Json为例)
resources 通常我们会把项目中需要动态加载的资源放在 resources 目录下,配合 resources.load 等接口动态加载。你只要传入相对 resources 的路径即可,并且路径的结尾处 不能 包含文件扩展名。 resources.load("Inf", JsonAsset, (error, ass…...
解决 IntelliJ IDEA 启动错误:插件冲突处理
引言 在使用 IntelliJ IDEA 进行开发时,我们可能会遇到各种启动错误。本文将详细介绍一种常见的错误:插件冲突,并提供解决方案。 错误背景 最近,有用户在启动 IntelliJ IDEA 时遇到了一个错误,提示信息为:…...
SQL——DQL分组聚合
分组聚合: 格式: select 聚合函数1(聚合的列),聚合函数2(聚合的列) from 表名 group by 标识列; ###若想方便分辨聚合后数据可在聚合函数前加上标识列(以标识列进行分组) 常见的聚合函数: sum(列名):求和函数 avg(列名)…...
Ripro V5日主题 v8.3 开心授权版 wordpress主题虚拟资源下载站首选主题模板
RiPro主题全新V5版本,是一个优秀且功能强大、易于管理、现代化的WordPress虚拟资源商城主题。支持首页模块化布局和WP原生小工具模块化首页可拖拽设置,让您的网站设计体验更加舒适。同时支持了高级筛选、自带会员生态系统、超全支付接口等众多功能&#…...
分布式搜索引擎之elasticsearch基本使用2
分布式搜索引擎之elasticsearch基本使用2 在分布式搜索引擎之elasticsearch基本使用1中,我们已经导入了大量数据到elasticsearch中,实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜索和数据分析。 所以j接下来,我们研究下…...
java学习-第十五章-IO流(java.io包中)
一、理解 1. 简单而言:流就是内存与存储设备之间传输数据的通道、管道。 2. 分类: (1) 按方向(以JVM虚拟机为参照物)【重点】 输入流:将中的内容读入到中。 输出流:将中的内容写入到中。 (2) 按单位: 字节流…...
企业如何实现数据从源端到消费端的全链路加工逻辑可视化?
要想实现数据加工链路的可视化,血缘图谱无疑是一个有效的工具。血缘图谱能够清晰地展示数据从产生、流转、加工到最终消费的每一个环节,帮助企业直观地理解数据之间的关联和依赖关系,轻松追溯数据来源和去向,并在数据出现问题时快…...
Toxicity of the Commons: Curating Open-Source Pre-Training Data
基本信息 📝 原文链接: https://arxiv.org/abs/2410.22587👥 作者: Catherine Arnett, Eliot Jones, Ivan P. Yamshchikov, Pierre-Carl Langlais🏷️ 关键词: toxicity filtering, language models, data curation📚 分类: 机器…...
Python 单例模式工厂模式和classmethod装饰器
前言: Python作为面向对象的语言,显然支持基本的设计模式。也具备面向对象的语言的基本封装方法:属性、方法、继承、多态等。但是,做为强大的和逐渐发展的语言,python也有很多高级的变种方法,以适应更多的…...
计算机键盘简史 | 键盘按键功能和指法
注:本篇为 “计算机键盘简史 | 键盘按键功能和指法” 相关文章合辑。 英文部分机翻未校。 The Evolution of Keyboards: From Typewriters to Tech Marvels 键盘的演变:从打字机到技术奇迹 Introduction 介绍 The keyboard has journeyed from a humb…...
【数字信号处理】期末综合实验,离散时间信号与系统的时域分析,离散信号 Z 变换,IIR 滤波器的设计与信号滤波,用窗函数法设计 FIR 数字滤波器
关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…...
Dedecms 手机网站示例/百度的广告推广需要多少费用
几种破解mysql root密码的几种方法: 方法一 使用phpmyadmin,这是最简单的了,修改mysql库的user表,不过别忘了使用PASSWORD函数。 方法二 使用mysqladmin,这是前面声明的一个特例。 mysqladmin -u root -p password mypasswd 输入。…...
郑州网站托管公司/网站设计的流程
http://www.liangjing.org/qiyejianzhan/Ch/Net_Index.html http://www.phpweb.net/index.php转载于:https://www.cnblogs.com/liulf/archive/2011/04/01/2002745.html...
做网站就/seo点击软件
这里主要总结下,在 Python 代码脚本里,涉及到调用 Shell 脚本、终端命令行、其它 Python 脚本的场景. 1. 方法1 - os.system() os.system() - 只返回状态码,执行结果会输出到stdout,即输出到终端. 仅在 Linux 中有效. 用法&#x…...
网站建设网络推广文章/个人网站首页设计
使用python制作ArcGIS插件(4)界面交互 by 李远祥 插件界面部分,除了一开始在设计器中设计的这些界面元素之外,还可以与操作系统进行一些输入输出的交互,这部分的实现全部在pythonaddins模块中。 pythonaddins模块包含了…...
wordpress 登录没反应/宁波seo专员
单链表(single-linked list)链表结构应用实例分析数据结构算法类方法对象代码实现插入向尾部直接插入节点思路分析算法实现按照顺序插入指定位置思路分析算法实现修改思路分析代码实现删除思路分析代码实现查找思路分析代码实现面试题有效元素的个数代码…...
做设计什么网站平台好点做私活/长春网站快速排名提升
2013-06-19 09:46:22 正在登录 10.21.34.206 ...2013-06-19 09:46:22 登录设备 10.21.34.206 成功2013-06-19 09:46:24 开始加固2013-06-19 09:46:29 加固前上传文件成功2013-06-19 09:46:42 加固前备份文件成功2013-06-19 09:46:42 仅使用ssh V2协议 (成功)2013-06-19 09:46:4…...