当前位置: 首页 > news >正文

蓝凌EKP产品:从 XML 到 JSON ——表单存储的性能优化实践

1. 背景介绍

蓝凌 EKP 的表单引擎,是整个低代码平台的核心能力之一。它不仅仅是“存储表单”,更是 企业级应用快速构建的基础设施

  • 它支持各种复杂表单配置(字段、布局、校验、权限、联动、子表单)。

  • 它能灵活绑定流程,实现 表单 + 流程 + 权限 的一体化管控。

  • 它为低代码应用提供了统一入口,业务人员通过拖拽和配置就能搭建应用,而无需写代码。

正是这种 强大、灵活、稳定 的能力,让我们的表单引擎能支撑上千种应用场景,从人事、财务、行政到项目、客户管理,真正成为企业数字化的核心引擎。


业务强大带来的新挑战

然而,随着业务场景越来越复杂,表单配置越来越灵活,表单数据存储的性能瓶颈也逐渐显现。

  • 我们早期选择 XML 存储表单值,非常合理:它层次清晰、可扩展、可校验,能快速支撑表单配置和跨系统兼容。

  • 但在今天,表单数量激增、字段量级庞大,XML 的 解析性能和存储冗余 成为用户体验的隐形负担。

为了让表单引擎在保持业务强大的同时,也能在性能上持续突破,我们开始探索 将存储方式从 XML 演进到 JSON


为什么要转向 JSON?

  • 更快:JSON 解析效率普遍高于 XML,能明显提升表单的加载速度。

  • 更轻:JSON 格式更紧凑,占用存储空间更小。

  • 更兼容:JSON 已经成为前后端交互的事实标准,更符合微服务和低代码平台的技术生态。

  • 更灵活:数据库(如 MySQL、Postgres、OceanBase)原生支持 JSON 类型,后续还能直接做查询和索引。

这一转变,不是推翻 XML,而是顺应业务发展、技术迭代的 优化升级

表单引擎已经足够强大,但强大也意味着要面对更高的性能挑战。选择从 XML 向 JSON 迁移,是我们在持续优化用户体验、提升系统性能道路上的又一次重要演进。

2. 问题分析

  • 性能瓶颈:XML 解析开销大,DOM 需要完整装载,SAX 流式复杂。

  • 存储冗余:XML 标签过长,大字段占用存储空间明显。

  • 兼容性差:前后端交互大多倾向于 JSON,XML 转换额外耗时。

  • 举例:某个大表单打

  • 开耗时 2s+,主要在 XML 解析环节。

3. 技术对比:XML vs JSON

表格形式更直观:

维度XMLJSON
数据格式标签结构键值对结构
存储大小冗余多,占用大紧凑,节省空间
解析速度慢(需逐层解析)快(轻量解析库)
可读性层次清晰更简洁
Schema 约束有 (XSD)弱(需额外方案)
生态兼容传统系统友好前端 & 微服务友好

4. 优化方案设计

  • 保留表单定义的层次化结构,但存储层改为 JSON。

  • 数据库层:如果 DB 支持 JSON 类型,可以直接用 JSON 字段;否则用 TEXT 存 JSON 字符串。

  • 应用层:使用 Jackson/Fastjson/Gson 替代 XML 解析器。

  • 兼容方案:老表单继续用 XML,新增表单优先用 JSON。


5. 实践过程

  • 贴代码示例:

XML 解析示例(原有实现)

将Map 表单集合转换为XML

    public static String objectXmlEncoder(Object obj)throws FileNotFoundException, IOException, Exception {ByteArrayOutputStream baos = new ByteArrayOutputStream();XMLEncoder encoder = new XMLEncoder(baos);encoder.setPersistenceDelegate(BigDecimal.class,bigDecimalPersistenceDelegate);encoder.writeObject(obj);encoder.flush();encoder.close();String rtnVal = new String(baos.toByteArray(), "UTF-8");baos.close();return rtnVal;}

将XML 转换为Map 表单集合

  String safeIns = ins.replaceAll("[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]", "");ByteArrayInputStream byteArrayInputStream = null;try{byteArrayInputStream = new ByteArrayInputStream(safeIns.getBytes("UTF-8"));//通过流读取转换成表单集合数据。return objectXmlDecoder(byteArrayInputStream);}finally{if(byteArrayInputStream!=null){byteArrayInputStream.close();}}

JSON 解析示例(优化后)

将Map 表单集合转换为XML

import com.fasterxml.jackson.databind.ObjectMapperprivate  static ObjectMapper mapper = null;
static {mapper = new ObjectMapper();mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL_AT_LEVEL,JsonTypeInfo.As.PROPERTY);
}//传入参数Map 集合 obj ,直接转换为xmlpublic static String objectJsonEncoder(Object obj) throws Exception{String string = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);return string;}

将XML 转换为Map 表单集合

    //读取xml 转换为表单Map集合
public static Map objectJsonDecoder(String obj) throws Exception{Map datas = mapper.readValue(obj, HashMap.class);return datas;}
  • 对比两段代码的简洁度。

为了考虑兼容性和提供给用户选择,提供了开关让用户选择xml 和json。


6. 性能对比实验

  • 描述测试环境:JDK 版本、表单大小(如 500 字段)、数据库类型。

  • 给出测试数据(例如:解析 1000 次表单的耗时对比)。

  • 示例表格:

测试场景XML 解析耗时JSON 解析耗时提升比例
小表单(50 字段)120ms40ms3x
大表单(500 字段)2100ms600ms3.5x

7. 收益与思考

  • 收益:表单打开速度更快,存储空间减少,系统响应更快。

  • 不足:JSON 缺乏严格约束,需要额外校验。

  • 未来:考虑进一步利用数据库 JSON 索引、缓存机制,提升查询效率。


8. 总结

  • XML 在早期合适,但随着系统演进,JSON 更适合高性能和前后端一体化。

  • 从 XML 到 JSON 的迁移,带来了 性能优化 + 存储优化 + 技术栈统一 的价值。

  • 希望本文的经验能为有类似困扰的开发者提供参考。

http://www.xdnf.cn/news/1359577.html

相关文章:

  • [自用笔记]上传本地项目至github
  • 【嵌入式开发 Linux 常用命令系列 8 -- git checkout 解冲突详细介绍】
  • Qt工具栏中图标槽函数没有响应的问题分析
  • 十一、redis 入门 之 数据持久化
  • 基于FPGA的情绪感知系统设计方案:心理健康监测应用(一)
  • yggjs_rlayout框架v0.1.2使用教程 01快速开始
  • 基于RBF-GA的铝/镁异材FSLW工艺参数优化研究
  • Qt---架构文件.pro
  • 02-开发环境搭建与工具链
  • 鸿蒙中点击响应时延分析
  • 多核多线程应用程序开发可见性和乱序如何处理
  • css3之flex布局
  • Linux 学习笔记 - 集群管理篇
  • 音视频学习(五十五):H264中的profile和level
  • pyecharts可视化图表-scatter:从入门到精通
  • Trip Footprint旅行足迹App
  • jar包项目自启动设置ubuntu
  • Vue中 this.$emit() 方法详解, 帮助子组件向父组件传递事件
  • Altium Designer 22使用笔记(9)---PCB布局、布线操作
  • 复杂街景误检率↓79%!陌讯时空建模算法在非机动车乱停放检测的实战解析
  • 点播视频预览是怎么做到的?
  • VsCode使用SFTP连接Linux
  • 使用 Golang 的 Gin 框架实现一周极限编程计划:全网 AIGC 项目热点追踪应用
  • MATLAB 与 Simulink 联合仿真:控制系统建模与动态性能优化
  • yggjs_rlayout框架v0.1.2使用教程 02 TechLayout 布局组件
  • 上科大解锁城市建模新视角!AerialGo:从航拍视角到地面漫步的3D城市重建
  • nginx部署goaccess监控
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day12
  • leetcode 1493 删掉一个元素以后全为1的最长子数组
  • mybatis过渡到mybatis-plus过程中需要注意的地方