FastJson序列化驼峰-下划线转换问题踩坑记录

fastJson 序列化 驼峰命名转下划线命名 1. 场景 在进行接口调用时,Java对象的属性命名一般是驼峰命名的,但第三方接口的入参对象是以下划线命名,这个时候进行交互时,就会匹配不到,导致接口调用失败。 2. 解决方案 使用注解即可。 3. 对象序列化的代码示例 Map<String,String> paramMap = JSON.parseObject(JSON.toJSONString(douyinProductUpdate), Map.class);marketPlaceCommonRequest.setParam(par 阅读详情
AI摘要

本文记录了FastJson序列化驼峰-下划线转换问题的踩坑过程。在MySQL更新写入时,字段名出现驼峰和下划线混用情况。经排查,问题是由序列化策略参数赋值与序列化执行先后关系,即RocketMq consumer bean和serializeConfig bean初始化顺序导致。最终选择添加两者依赖关系的方案解决问题。

背景

问题描述

在MySQL数据表中,存在一个JSON结构的扩展字段,通过updateById进行更新写入操作。更新写入的同一个字段名出现了混合使用了驼峰命名和下划线命名两种格式。
ps: FastJson版本是1.2.83

问题影响

数仓同学离线统计数据时发现字段名有两种定义,产生了迷惑,不清楚如何统计;对线上实时链路还无任何影响。

原因定位

  • 首先例行公事,先检查多机房部署的代码版本是否一致,类似数据是否有持续写入
    • 检查过后发现,多区代码部署版本完全一致;
    • 且数据字段命名驼峰&下划线同时存在的数据持续有写入;
  • 检查下代码中是否有不同的写入位置,且写入的字段定义规则不一致
    • 发现这个字段只有一处更新写入,且通过业务日志看这个字段没有任何问题;
  • 尝试测试环境复现
    • 首先检查了下测试环境是否存在类似数据,发现并没有;
    • 其次在测试环境尝试构造请求写入,并未复现;
  • 到了常规猜测环节
    • 首相想到的是否有配置了全局的fastjson序列化驼峰下划线转换配置
      • 发现确实是有配置的,全局配置成了驼峰格式转换为下划线;配置如下:
@Configuration
public class FastJsonConfig {

    @Bean
    public SerializeConfig serializeConfig(){
        SerializeConfig serializeConfig = SerializeConfig.getGlobalInstance();
        serializeConfig.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
        return serializeConfig;
    }
}
  • 那么新的问题来了,配置了全局转换为下划线的情况呢?
    首先在mybatis Xxx.xml 中的update语句里有
<if test="extraInfo != null">
        extra_info = #{extraInfo, typeHandler=com.xxx.config.typehandler.JsonTypeHandler},
</if>

result里面配置有如下转换:

<result column="extra_info" jdbcType="VARCHAR"
            javaType="com.xxx.dao.model.SoundtrackDO$SoundtrackExtraInfo"
            typeHandler="com.xxx.config.typehandler.JsonTypeHandler"
            property="extraInfo"/>

JsonTypeHandler 的代码如下:

public class JsonTypeHandler<T> extends BaseTypeHandler<T> {

    private Class<T> type;

    public JsonTypeHandler(Class<T> type) {
        this.type = type;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setString(i, JSON.toJSONString(parameter));
    }

    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return parseObject(rs.getString(columnName));
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return parseObject(rs.getString(columnIndex));
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return parseObject(cs.getString(columnIndex));
    }

    private T parseObject(String result) {
        return JSON.parseObject(result, type);
    }
}

从配置代码上没有看出任何毛病,自测也是符合预期,一切都像是那么合理,为什么线上环境就出现了意外场景呢?依然很疑惑。
到了这里头上顶了三个问号,难道说这跟bean的初始化顺序有关?因为这个场景我们是消费rocketMq消息后调用mysql的更新语句,也就会执行到JsonTypeHandler这里的代码;而这里如果是消费者bean先初始化完成,代码开始消费,而此时序列化全局配置bean还没初始化完成是不是就用了默认的序列化规则呢,看起来很合理的猜测,所以我们开始了验证:

首先验证默认情况:
在这里插入图片描述
在这里插入图片描述
从图上看默认是驼峰,很符合预期;
那我们就尝试复现下先序列化,在设置全局参数的场景:
在这里插入图片描述
在这里插入图片描述
我们是先开启线程1序列化输出ss1,主线程睡眠两秒后,执行全局赋值驼峰下划线转换策略,再开启线程2,序列化输出ss2;从执行结果中可以看出,问题已经出现了,在我们设置驼峰转下划线格式后,ss2输出的依然是驼峰格式。
至此我们基本定位问题为:序列化策略propertyNamingStrategy参数赋值与序列化执行先后关系导致;从业务代码角度来说的话,就是RocketMq consumer bean初始化(因为初始化后,有消息就会立即消费,并不会等所有不强相关bean都初始化完成) 与 serializeConfig bean初始化先后顺序导致;测试环境因为消息太少所以没有命中这个问题。

接下来我们又提出个疑问,1.我们可以看到JSON.toJSONString方法是每次执行都会去获取SerializeConfig.globalInstance,那么如果每次都获取是不是服务启动完成后,就恢复了呢,但从数据库的数据上看并不是;
通过debug我们发现,fastjson 对一个对象首次序列化之后会将其存储再一个容器内com.alibaba.fastjson.serializer.SerializeConfig#serializers;后续在对这个对象序列化时是通过获取容器中存储的序列化规则进行处理的,并不是重新获取一遍配置,这也就是为啥服务启动完成后没有恢复的原因;也是fastjson的一个提升性能的设计。
对于为什么在线链路没有出现问题,这就是fastjson的一个机制了,反序列化时会先匹配字段名完全相同的字段值,没有的情况下还会匹配对应的驼峰或者下划线格式的字段名进行赋值,所以从接口返回上看不出问题。
好了,问题已经定位完成,后续就是如何解决了;

解决方案

1.提高serializeConfig bean的加载时机

例如在serializeConfig 配置处添加 @Order(1) 注解

但这个方式后续如果有人调整调整优先级可能会重新出现这个问题;
2.添加Consumer bean和 serializeConfig bean的依赖关系

例如在Consumer bean上配置@DependsOn("serializeConfig")

这样影响范围最小,切不会轻易受到其他调整的影响
3.抛弃serializeConfig全局配置,在使用场景进行单独处理,这个就是乱说了,这种场景完全不敢尝试,虽说看起来是短痛;不在有类似的问题出现,但过于痛,可能会踩大坑,不建议。

最终选择方案2

总结一下

1.这种全局配置要谨慎使用,且这种加载优先级设置还不是最高的,且不好被开发人员发现的配置话尽量少用吧,避免坑自己更避免坑别人
2.对于老服务,还是需要多观察下配置

gson 下划线转驼峰 注解_Java开发里遇到的奇奇怪怪的需求---JSON键值驼峰转下划线的实现... 上周在与第三方对接接口的时候,由于三方的接口key值均是采用下划线命名的方式,使用传统的JSONObject方式,需要挨个赋值,特别麻烦,而且一点也不面向对象,一点也不极客。大概实现的效果就是上图这样,三方接口提供的无论是入参还是接参,均是下划线分隔的,接口的需求是驼峰的和下划线分隔的均需要能正常接收,并进行业务逻辑处理,好了,话不多说,上代码!代码见:jjn0942/jackson-demo-p... 阅读详情

相关推荐

前后端分离命名规范:JSON下划线,对象小驼峰,以及Jackson常用配置

前后端分离命名规范:JSON下划线,对象小驼峰,以及Jackson常用配置

xzx18822942899的博客 1159

FastJson 下划线转驼峰

开发中存在一个需求,需要将下划线的json字符串,用驼峰的实体类接收。 @Data @ToString public class User{ private String userName; } 第一种 查了一些资料,提供了如下方法 进行转化: String str = "{\"user_name\":123}"; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setPropertyNamingStrategy(com.fast

my博客 6203

Java JSON处理实战:Jackson、Gson与Fastjson2选型与避坑指南

JSON序列化与反序列化是Java后端开发中处理接口数据、配置存储和第三方调用的基础技术,其核心原理涉及对象与JSON的互转、泛型处理及注解映射。合理选择Jackson、Gson或Fastjson2等库,能有效解决字段命名不一致、日期格式转换、大数字精度丢失等工程痛点,提升系统稳定性和性能。在微服务接口、数据导出、缓存序列化等场景中,掌握流式解析与自定义序列化技巧尤为关键。本文围绕Java JSON处理,深入对比三大主流库的选型逻辑与实战避坑经验。

weixin_34174322的博客 373

FastJson下划线转驼峰

parse(字符串转对象)的时候 设置下划线转驼峰 ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase; JSON.parseObject(str, RespOrderDTO.class); toString(对象转字符串)的时候,设置下划线转驼峰 Serialize...

qq_41959009的博客 2万+

Java实体与Map转换全解析:从反射、序列化库到性能优化实践

在Java开发中,对象与字典结构的相互转换是数据处理的基础操作,涉及序列化、ORM映射和动态配置等核心场景。其原理在于桥接强类型的对象世界与弱类型的字典世界,需要在类型安全、性能与灵活性之间取得平衡。这项技术的价值在于提升代码的通用性和动态处理能力,是构建灵活数据管道的关键。实践中,开发者常面临反射性能陷阱、类型转换异常等挑战。通过对比手动编码、反射工具、Jackson/Gson等序列化库以及Spring/Hutool框架方案的优劣,可以针对不同场景选择最优解。例如,在需要处理JSON交互和高性能序列化的微

weixin_33965305的博客 513

Java JSON解析框架深度对比:Jackson、Gson、Fastjson与Json-lib选型指南

JSON作为一种轻量级的数据交换格式,在现代软件开发中扮演着核心角色,尤其在Web API、微服务通信和配置文件解析等场景中不可或缺。其核心原理是基于文本的键值对集合,易于人阅读和编写,也易于机器解析和生成。在Java生态中,高效、安全地处理JSON数据是提升应用性能和稳定性的关键技术。不同的JSON解析框架在实现原理上各有侧重,例如通过流式解析降低内存占用,或利用反射机制简化API。这些技术选择直接影响着开发效率、系统性能和数据安全性。对于企业级应用而言,框架的社区活跃度、安全漏洞修复及时性以及与Spri

weixin_32821533的博客 240

FastJson序列化和反序列化问题记录

序列化与反序列化问题;

lonelymanontheway的博客 1001

SpringBoot中Jackson ObjectMapper配置、注解与实战避坑指南

JSON序列化与反序列化是现代Web开发中处理数据交换的基础技术,其核心原理是将内存中的对象结构转换为可传输或存储的字符串格式,反之亦然。这项技术对于构建高效、可维护的RESTful API和微服务架构具有关键价值,广泛应用于前后端分离、服务间通信和数据持久化等场景。在Java生态中,Jackson库因其强大的功能和稳定性成为SpringBoot项目的默认选择。本文聚焦于Jackson的核心组件ObjectMapper,深入解析其配置项、常用注解及性能优化策略,旨在帮助开发者解决日期格式处理、多态类型序列化

优快云头条 491

从fastjson到Jackson:反序列化漏洞的底层逻辑与迁移实践

在Java服务开发中,JSON序列化与反序列化是数据交换的基础技术,而反序列化漏洞则是安全攻防的高危地带。fastjson因AutoType机制允许外部输入指定类加载,将安全决策权交予不可信数据源,导致攻击者可利用JNDI、RMI等链路实现远程代码执行。其黑名单修补策略天然滞后,补丁循环让团队疲于应对,且1.x已进入维护末期。相比之下,Jackson默认禁用多态反序列化,安全边界清晰,通过显式配置即可兼顾功能与可控性。本文从反序列化原理切入,剖析fastjson漏洞频发的根因,对比API差异,并提供从依赖扫

weixin_34007886的博客 336

Sw模块JSON交互实战:从序列化到配置管理的完整指南

JSON作为一种轻量级、跨语言的数据交换格式,其核心原理在于通过键值对集合和有序列表两种基本结构,构建出可嵌套的树形数据结构。这一特性使其在序列化与反序列化过程中,能够高效地在内存对象与文本格式间转换,奠定了现代软件模块间数据通信的技术基础。其技术价值在于提供了标准化的数据表示方法,极大简化了异构系统间的集成复杂度。在工程实践中,JSON广泛应用于API通信、配置文件管理、消息队列及数据持久化等场景。本文聚焦于Sw模块与JSON的深度交互,通过解析Python、Java等主流语言中的高性能处理库(如orjs

weixin_33970449的博客 547

28GHz毫米波滤波器设计实战:用SynMatrix快速搞定SIW带通滤波器(附完整参数)

本文详细介绍了如何使用SynMatrix工具链高效设计28GHz SIW带通滤波器,涵盖智能参数预测、多物理场联合优化和加工误差补偿等核心技术。通过实战案例和完整参数模板,帮助射频工程师快速实现毫米波滤波器设计,显著提升工作效率并避免反复迭代。

weixin_29284657的博客 496

jackson与fastjson

json

xuxuxux123的博客 5503

DIC新手避坑指南:压缩实验中的应变测量常见错误与数据校验技巧

本文为DIC技术新手提供了压缩实验中应变测量的全面避坑指南。文章系统梳理了从试样尺寸录入、散斑质量到数据后处理中应变方向与符号混淆、数据插值对齐等常见错误,并分享了基于MATLAB的自动化数据校验与可视化对比技巧,帮助建立可靠的实验数据分析SOP,确保DIC测量结果的准确性。

weixin_29313423的博客 115

Java中JSON 序列化与反序列化 — 概念、原理与实践

本文介绍了Java中JSON序列化与反序列化的核心概念、原理与实践方法。主要内容包括: 基本概念:序列化是将Java对象转为字符串/字节流,反序列化则是逆向过程,用于网络传输、微服务调用等场景。 JSON格式:作为通用数据交换格式,支持字符串、数字、布尔、对象、数组等数据类型。 主流框架:对比了Jackson(Spring默认)、Fastjson(阿里高性能)和Gson(Google轻量级)三种框架。 核心原理: 序列化:通过反射获取对象字段,转换为JSON键值对 反序列化:解析JSON为Token流,填充

BADAO_LIUMANG_QIZHI的博客 187

数字蓝军智能体关键技术课题研究

本研究提出基于人工智能大模型技术构建智能数字蓝军智能体系统,旨在提升作战模拟推演的智能化水平。系统采用"大模型+小模型"混合架构,整合感知、决策、规划、学习等核心模块,实现动态、智能的作战方案生成。关键技术包括大模型与知识图谱融合、多智能体协同、战场态势数字化表示等。研究成果将形成可复用的垂直领域智能体框架,为军事训练提供智能化对抗平台。该系统不仅能模拟真实对手的决策行为,还能通过自我博弈持续进化,有效增强推演的真实性和对抗性。

weixin_49042442的博客 1549

定时移动鼠标点击鼠标,防止电脑息屏的vba脚本

定时移动鼠标,使系统始终处于激活状态,防止系统息屏。

panfei263031的博客 5932

json序列化

}

qq_36851469的博客 1426

chipseeker Y叔

这一次讲解非常重要的peak注释,注释在ChIPseeker里只需要用到一个函数annotatePeak,它可以满足大家各方面的需求。 输入 当然需要我们上次讲到的BED文件,ChIPseeker自带了5个BED文件,用getSampleFiles()可以拿到文件的全路径,它返回的是个named list,我这里取第4个文件来演示。annotatePeak的输入也可以是GRanges对象,你如果用R做peak calling的话,直接就可以衔接上ChIPseeker了。 require(ChIPseeke

生信小博士的博客 1590

Java实体与JSON转换实战:从原理到性能调优的避坑指南

序列化与反序列化是数据交换的核心技术,它负责将内存中的对象转换为可传输或存储的文本格式(如JSON),反之亦然。其原理在于通过字段映射、类型转换和结构处理,实现对象状态与文本数据的双向“翻译”。这项技术的价值在于打通异构系统间的数据流通,是构建现代分布式应用和API接口的基石,广泛应用于微服务通信、前后端数据交互和持久化存储等场景。在实际开发中,若处理不当,极易引发如循环引用导致的栈溢出、日期时区错乱、以及大JSON解析时的内存溢出等线上故障。本文以Jackson、Gson等主流工具为例,深入剖析如何通过注

weixin_33806859的博客 307

【超详细】基于YOLOv8的PCB缺陷检测

印刷电路板(PCB)瑕疵数据集:是一个公共的合成PCB数据集,由北京大学发布,其中包含1386张图像以及6种缺陷(缺失孔,鼠标咬伤,开路,短路,杂散,伪铜),用于检测,分类和配准任务。本文我们选取了其中适用与检测任务的693张图像,随机选择593张图像作为训练集,100张图像作为验证集。

weixin_45679938的博客 2万+

LVGL v8学习笔记 | 09 - 进度条控件的使用方法(bar)

lv_bar_set_range必须放在lv_bar_set_mode前面,否则不生效。bar对象的API在lv_bar.h中声明,以lv_bar_xxx命名。此事件可以用来在进度条更新值之后更新别的控件(比如进度条旁边的文字)。可以看到,默认创建的进度条值是0到100。(3)设置进度条的范围值(最大值和最小值)(2)获取进度条的起始值。(3)获取进度条的最小值。(4)获取进度条的最大值。(1)设置进度条的当前值。(2)设置进度条的起始值。(1)获取进度条当前值。(5)获取进度条的模式。

Mculover666的博客(嵌入式) 1730

JSON字符串转JSON, 字段名不一致

前言 不知道你有没有遇到json字符串转对象,字段需要从下划线转驼峰命名问题?\color{red}不知道你有没有遇到json字符串转对象,字段需要从下划线转驼峰命名问题?不知道你有没有遇到json字符串转对象,字段需要从下划线转驼峰命名问题? 不知道你有没有遇到json字符串转对象,字段名和对象属性字段对不上问题?\color{red}不知道你有没有遇到json字符串转对象,字段名和对象属性字段对不上问题?不知道你有没有遇到json字符串转对象,字段名和对象属性字段对不上问题? 最近刚好遇到这两类问题,记

xiaozhegaa的博客 3080

基于计算机视觉的无人便利店技术:从算法到部署的系统化实战指南

摘要:本文系统介绍了基于计算机视觉的无人便利店技术方案,提出"商品检测-跟踪-动作识别-防损-结算"五段式流水线架构。详细阐述了YOLOv8-Seg商品检测、OC-Sort多目标跟踪、3D-CNN+ST-GCN动作识别等核心算法实现,并完成NVIDIA Jetson Xavier NX边缘端的优化部署。通过TensorRT量化、DeepStream加速等技术手段,系统在保持94.7%动作识别准确率的同时,将漏单率降至0.8%,单店云端算力成本较行业平均降低84%。所有代码已开源,可直接应

博客 626

Java实现王者营地数据解析:从HTTP请求到JSON解析实战

在Java开发中,解析外部接口数据是一项基础且高频的工程实践,其核心链路往往围绕HTTP请求构建与JSON数据解析展开。通过合理选择HTTP客户端库(如Apache HttpClient)并配置超时、请求头等参数,可以稳定获取远程数据;而借助成熟的JSON解析库(如Fastjson2)配合泛型响应体与容错设计,则能将复杂结构安全地映射为Java对象。这一套技术组合广泛应用于用户画像分析、游戏数据统计、报表生成等场景。本文以王者营地营地号作为数据入口,演示如何将玩家战绩、英雄池、皮肤数量等字段从接口原始响应中

weixin_33898233的博客 292

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

JSON实战全解析:从规范细节到多语言避坑与高级应用

JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,其核心原理在于基于文本、独立于语言的键值对结构,易于人阅读和机器解析。这一特性使其在现代软件开发中展现出巨大的技术价值,成为连接前后端、微服务及配置管理的通用数据桥梁。在实际应用场景中,开发者常需处理如数据校验、格式转换与性能优化等工程实践问题。例如,通过JSON Schema可定义严格的数据契约以确保接口健壮性,而针对Python登录等场景,需明确区分表单提交与JSON提交的Content-Type设置。本文聚焦

cuiji1279的博客 427

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java JSON处理实战:Jackson核心用法、安全考量与生产实践

JSON作为一种轻量级的数据交换格式,已成为现代软件系统中数据序列化与网络传输的基石。其基于文本、易于阅读和跨语言的特性,使得它在RESTful API、微服务通信和配置文件等场景中广泛应用。在Java生态中,将JSON与Java对象相互转换的核心机制是数据绑定,它通过约定或配置建立JSON结构与Java类字段间的映射关系。Jackson库凭借其高性能、丰富的功能集和强大的社区支持,成为实现这一过程的主流选择,尤其在Spring Boot等框架中作为默认集成。相较于Fastjson等库,Jackson在安全

weixin_30721077的博客 272

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: 文件行数计算及文件拆分
code1Boy
博客等级 码龄10年 45粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值