在现代软件开发中,JSON(JavaScript Object Notation)已成为数据交换的“通用语言”——从前后端接口通信到微服务数据交互,从配置文件解析到日志格式化,几乎所有场景都离不开JSON的处理。然而,原生JSON框架(如FastJSON、Jackson)的API往往需要大量重复代码,且空指针、格式异常等问题频发。

本文分享的JsonUtil工具类,基于FastJSON、Jackson等主流框架封装,整合了18+高频功能,从基础的格式转换到复杂的JSON合并,从安全的字段提取到批量内容替换,全方位覆盖开发需求。下文将从核心能力、源码解析、实战场景、优势对比等维度展开,帮助开发者彻底掌握JSON高效处理技巧。

一、JsonUtil核心能力全景:从基础到复杂场景

JsonUtil的设计遵循“业务驱动”原则——所有方法均源自实际开发中的高频需求。其核心能力可分为六大类,覆盖JSON处理的全生命周期:

1. JSON合并:多源数据整合的终极方案

在微服务架构中,一个业务数据往往需要从多个接口获取(如商品详情需合并基础信息、库存、评价等接口数据);在前端开发中,组件数据可能来自多个数据源。JsonUtil的合并能力正是为解决这类问题设计,支持JSONObjectJSONArray两种合并场景。

  • JSONObject合并(jsonMerge:以目标JSON为基础,用源JSON的字段覆盖或递归合并(支持嵌套结构)。
  • JSONArray合并(jsonArrayMerge:将两个数组元素合并为新数组,支持嵌套JSON的深拷贝。

2. 格式转换:对象与JSON的无缝衔接

对象与JSON的转换是日常开发中最频繁的操作之一。JsonUtil封装了多种转换逻辑,支持“对象→JSON字符串”“JSON字符串→对象”“集合→JSONArray”等全场景。

  • 基础转换fromJsonStringToT(JSON字符串→对象)、objectToJson(对象→JSONObject)。
  • 集合转换jsonToList(JSON→List)、listToJsonArray(List→JSONArray)。
  • Map转换jsonToMap(JSON→Map)、jsonToList(JSON→List)。

3. 安全提取:从JSON中获取字段的“防坑”实践

直接从JSON中提取字段时,若字段不存在或类型不匹配,极易抛出NullPointerException或类型转换异常。JsonUtil的提取方法通过“默认值兜底”机制,彻底解决这类问题。

  • 基础类型提取getString(默认空串)、getInt(默认0)、getBoolean(默认false)。
  • 复杂类型提取getJsonObject(默认null)、getJsonArray(默认null)。

4. 校验与修改:JSON格式校验与内容批量处理

在接收外部数据(如用户输入、第三方接口返回)时,需先校验JSON格式合法性;在日志处理、数据清洗场景中,需批量修改JSON中的特定内容。JsonUtil提供了完整的校验与修改能力。

  • 格式校验isJsonStr(FastJSON校验)、isGsonStr(Gson校验)。
  • 内容修改replaceStringInJson(递归替换JSON中的字符串)。

5. 自定义转换:按需过滤字段的轻量方案

有时需要将对象转换为JSON,但仅保留部分字段(如接口返回时隐藏敏感字段)。JsonUtil的自定义转换方法通过反射实现字段过滤,无需手动构建Map。

  • listToStringIncludeArrays(List对象→仅含指定字段的JSON)。
  • objectToStringIncludeArrays(单个对象→仅含指定字段的JSON)。

6. 深拷贝:避免引用传递的“独立副本”生成

JSON对象默认是引用传递,修改拷贝对象可能影响原对象。JsonUtil的合并、转换方法中内置深拷贝逻辑,通过序列化实现对象的完全独立。

二、核心方法深度解析:从源码到原理

1. JSON合并(jsonMerge):递归逻辑与边界处理

业务场景:电商商品详情页需要合并“基础信息接口”(含名称、价格)和“库存接口”(含库存数量、仓库位置)的返回数据,且需保留双方的非重复字段。

方法作用:用source(源JSON)的字段覆盖target(目标JSON)的同名字段,若字段是嵌套JSONObject则递归合并,若为JSONArray则按索引合并元素。

源码核心逻辑

public static JSONObject jsonMerge(JSONObject source, JSONObject target) {if (source == null) return target;if (target == null) return source;try {for (String key : source.keySet()) {Object value = source.get(key);// 1. 目标JSON不含该key:直接添加if (!target.containsKey(key)) {target.put(key, value);continue;}// 2. 字段是JSONObject:递归合并if (value instanceof JSONObject) {JSONObject mergedValue = jsonMerge((JSONObject) value, target.getJSONObject(key));target.put(key, mergedValue);continue;}// 3. 字段是JSONArray:按索引合并元素(需长度一致)if (value instanceof JSONArray) {JSONArray sourceArray = (JSONArray) value;JSONArray targetArray = target.getJSONArray(key);if (sourceArray.size() != targetArray.size()) {throw new IllegalArgumentException("数组长度不一致:" + key);}for (int i = 0; i < sourceArray.size(); i++) {Object sourceItem = sourceArray.get(i);Object targetItem = targetArray.get(i);// 仅合并数组中的JSONObject元素if (sourceItem instanceof JSONObject && targetItem instanceof JSONObject) {targetArray.set(i, jsonMerge((JSONObject) sourceItem, (JSONObject) targetItem));}}continue;}// 4. 其他类型(字符串、数字等):直接覆盖target.put(key, value);}} catch (Exception e) {logger.error("JSON合并失败", e);throw new RuntimeException("合并失败", e);}return target;
}

关键设计

  • 递归处理嵌套JSON:若字段是JSONObject,通过自身递归实现深层合并(如{"a":{"b":1}}{"a":{"c":2}}合并为{"a":{"b":1,"c":2}})。
  • 数组长度校验:避免因数组长度不一致导致的索引越界(如合并商品图片数组时,确保双方图片数量相同)。
  • 异常兜底:合并失败时记录日志并抛出运行时异常,避免静默失败(如生产环境中数据合并错误需及时报警)。

2. 安全提取(getStringgetInt):空值处理的最佳实践

业务痛点:从接口返回的JSON中获取“用户手机号”时,若接口未返回该字段,直接调用json.getString("phone")会返回null,后续调用phone.length()将抛出空指针异常。

方法作用:获取字段值时,若字段不存在或为null,返回预设默认值(字符串返回空串,整数返回0)。

源码解析

public static String getString(JSONObject jsonObject, String key) {// 若jsonObject为null,或字段值为null,返回空串return Objects.nonNull(jsonObject) && Objects.nonNull(jsonObject.getString(key)) ? jsonObject.getString(key) : "";
}public static int getInt(JSONObject jsonObject, String key) {// 若jsonObject为null,或字段值为null,返回0return Objects.nonNull(jsonObject) && Objects.nonNull(jsonObject.getInteger(key))? jsonObject.getInteger(key): 0;
}

使用示例

JSONObject userJson = JSON.parseObject("{\"name\":\"张三\"}");// 安全获取存在的字段
String name = JsonUtil.getString(userJson, "name"); // "张三"// 安全获取不存在的字段(返回空串,避免null)
String phone = JsonUtil.getString(userJson, "phone"); // ""// 安全获取整数(不存在返回0,避免空指针)
int age = JsonUtil.getInt(userJson, "age"); // 0

3. 自定义转换(objectToStringIncludeArrays):反射过滤字段

业务场景:用户列表接口需要返回用户信息,但仅保留“id”“name”字段,隐藏“password”“idCard”等敏感信息。

方法作用:通过反射获取对象的指定字段值,生成仅含这些字段的JSON字符串,无需手动创建Map。

源码核心逻辑

// 核心工具方法:将对象转换为仅含指定字段的Map
private static Map<String, Object> objectToMapIncludeArrays(Object object, String[] arrays) {Map<String, Object> result = new HashMap<>();for (String fieldName : arrays) {if (object instanceof Map) {// 若对象是Map,直接取key对应的值result.put(fieldName, ((Map<?, ?>) object).get(fieldName));} else {// 若对象是普通实体,通过反射获取字段值try {Object value = getFieldValueByObject(object, fieldName);result.put(fieldName, value);} catch (Exception e) {logger.error("反射获取字段值失败", e);}}}return result;
}// 反射获取字段值(支持父类字段)
private static Object getFieldValueByObject(Object object, String targetFieldName) throws Exception {Class<?> objClass = object.getClass();// 先查当前类字段for (Field field : objClass.getDeclaredFields()) {if (field.getName().equals(targetFieldName)) {field.setAccessible(true); // 突破私有字段访问限制return field.get(object);}}// 再查父类字段(如User类继承自BaseEntity,需获取父类的id字段)Class<?> superClass = objClass.getSuperclass();if 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93365.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93365.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/93365.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 库手册:xmlrpc.client 与 xmlrpc.server 模块

xmlrpc.client 和 xmlrpc.server 是 Python 标准库中用于构建基于 XML-RPC 协议的远程过程调用&#xff08;RPC&#xff09;通信模块。xmlrpc.client 用于编写客户端程序&#xff0c;向远程服务器发起方法调用。xmlrpc.server 用于编写服务器端&#xff0c;暴露本地方法供远程客…

渲染篇(一):从零实现一个“微型React”:Virtual DOM的真面目

渲染篇(一)&#xff1a;从零实现一个“微型React”&#xff1a;Virtual DOM的真面目 引子&#xff1a;前端性能的“永恒之问” 在前面两章中&#xff0c;我们已经奠定了坚实的架构基础。我们用“任务调度器”建立了声明式和模块化的编程范式&#xff0c;并通过对比MVC等模式论…

SWC 深入全面讲解

一、核心功能与原理 1. 高性能编译 Rust 架构优势&#xff1a;SWC 基于 Rust 编写&#xff0c;利用 Rust 的性能和并发性优势&#xff0c;编译速度比 Babel 快约 20 倍&#xff0c;比 TypeScript 编译器更快。并行编译&#xff1a;支持多线程并行处理&#xff0c;在四核基准测试…

XML Expat Parser:深入解析与高效应用

XML Expat Parser:深入解析与高效应用 引言 XML(可扩展标记语言)作为一种广泛使用的标记语言,在数据交换、存储和表示中扮演着重要角色。XML Expat Parser 是一个高性能、可扩展的XML解析库,广泛应用于各种编程语言中。本文将深入探讨XML Expat Parser 的原理、特性以及…

【Python】自动化GIT提交

在日常开发中&#xff0c;我们经常需要频繁地向 Git 仓库提交代码。虽然 git add、git commit、git push 这几个命令并不复杂&#xff0c;但重复操作容易出错&#xff0c;也浪费时间。本文将介绍如何使用 Python 脚本自动化完成 Git 提交流程&#xff0c;让开发更高效&#xff…

基于Qlearning强化学习的水下无人航行器路径规划与避障系统matlab性能仿真

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.算法涉及理论知识概要 5.参考文献 6.完整算法代码文件获得 1.引言 水下无人航行器 (Autonomous Underwater Vehicle, AUV) 的路径规划与避障是海洋探索、资源开发和军事应用中的关键技术。传统的路径规划方…

模块自由拼装!Python重构DSSAT作物模块教程(以杂交水稻为例)

基于过程的作物生长模型&#xff08;Process-based Crop Growth Simulation Model&#xff09;在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农业碳中和、农田固碳减排等领域扮演着越来越重要的作用。Decision Support Systems for Agrotechnology Tr…

Java项目接口权限校验的灵活实现

引言 在Java Web开发中&#xff0c;接口权限校验是保护系统资源安全的关键机制。本文将介绍一种灵活、可配置的接口权限校验方案&#xff0c;通过注解驱动和拦截器实现&#xff0c;既能保证安全性&#xff0c;又能灵活控制哪些接口需要校验。 设计思路 实现方案的核心设计要点&…

瀚高DB兼容MySQL if函数

文章目录环境症状问题原因解决方案环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5 症状 MySQL if函数在瀚高DB当中没有&#xff0c;源应用在用到if函数时&#xff0c;就会报if函数不存在的错误信息。为此&#xff0c;我们需要根据业…

基于深度学习的胸部 X 光图像肺炎分类系统(六)

目录 结果指标解读 一、为什么选择这些指标&#xff1f; 二、各指标的定义和解读 1. 准确率&#xff08;Accuracy&#xff09; 2. 损失&#xff08;Loss&#xff09; 3. 精确率&#xff08;Precision&#xff09; 4. 召回率&#xff08;Recall&#xff09; 三、这些指标…

区块链性能优化策略:从理论到实践

目录 区块链性能优化策略:从理论到实践 1. 引言:区块链性能的挑战 2. 性能评估指标 2.1 核心性能指标 2.2 性能瓶颈分析 3. 分层优化策略 3.1 网络层优化 3.1.1 Gossip协议改进 3.1.2 网络分片 3.2 共识层优化 3.2.1 PBFT优化 3.3 数据层优化 3.3.1 状态树优化 3.3.2 区块数据…

【VLLM】open-webui部署模型全流程

目录 前言 一、租用服务器到服务器连接VScode全流程(可选) 二、下载模型到本地服务器 2.1 进入魔塔社区官网 2.2 选择下载模型 2.3 执行下载 三、部署VLLM 3.1 参考vllm官网文档 3.2 查看硬件要求 3.3 安装vLLM框架 3.4 启动模型服务 方法1:直接启动下载的本地模…

办公自动化入门:如何高效将图片整合为PDF文档

将多张图片合并到一个PDF文件中可以帮助保持特定的顺序和布局&#xff0c;同时确保图像的质量不会因为格式转换而下降。它是免费&#xff0c;不限次数&#xff0c;批量导入也毫无压力。操作堪比发朋友圈&#xff1a;拖图进来 → 选个纸张尺寸 → 点击转换 → 指定保存路径&…

使用宝塔面板搭建 PHP 环境开发一个简单的 PHP 例子

目录一、引言二、准备工作2.1 服务器选择2.2 下载安装宝塔面板三、使用宝塔面板搭建 PHP 环境3.1 登录宝塔面板3.2 选择 Web Server3.3 安装 PHP3.4 安装 MySQL 数据库四、开发一个简单的 PHP 例子4.1 创建 PHP 文件4.2 编写 PHP 代码4.3 设置站点4.4 访问 PHP 页面五、常见问题…

AWS WebRTC:我们的业务模式

拉流、卡录基本流程 设备端&#xff08;摄像机&#xff09; 与 App端 是通过 AWS KVS WebRTC 信令服务进行“点对点连接”的&#xff0c;真正的媒体数据&#xff08;音视频&#xff09;是通过 WebRTC 的 ICE 通道&#xff08;P2P 或 TURN&#xff09;直接传输的&#xff0c;而不…

使用Python,OpenCV,K-Means聚类查找图像中最主要的颜色

使用Python&#xff0c;OpenCV&#xff0c;K-Means聚类查找图像中最主要的颜色 分别把跑图聚类选取1, 2, 3&#xff0c;4, 5, 6, 7&#xff0c;8, 9种主要颜色并绘制colormap颜色图; 效果图 分别把跑图聚类选取3&#xff0c;4, 5&#xff0c;7&#xff0c;9种主要颜色并绘制…

DBAPI 实现分页查询的两种方法

DBAPI 实现分页查询的两种方法 背景 在进行分页查询时&#xff0c;用户通常需要传入当前页码 pageNo 和每页显示的条数 pageSize 参数。根据这两个参数&#xff0c;我们可以从数据库中查询出当前页的数据。以 MySQL 为例&#xff0c;分页查询的 SQL 语句如下&#xff1a; se…

第五天上课 SSLPolicy策略和Network Discovery技术

SSL Policy场景1:拥有自家服务器的私钥&#xff0c;解密访问自家服务器的ssl流量场景2: 内部用户访问互联网的ssl流量&#xff0c;需要解密并重签名Correlation and Compliance相关性与合规性配置相关性与合规性策略&#xff0c;在10.1.1.0/24网络中&#xff0c;当通过Network …

进阶07:C#与通用OPC UA通信范例

本节目标&#xff1a; 1&#xff09;安装软件&#xff0c;搭建虚拟OPC UA服务器&#xff1b; 2&#xff09;使用UaExpert&#xff0c;读取OPC UA服务器中的变量&#xff1b; 3&#xff09;编写Winform程序&#xff0c;读写服务器中变量值&#xff0c;创建订阅触发事件&#…

大模型微调学习笔记(基于讯飞星辰MaaS速学版)

文章目录参考资料说明大模型微调入门微调简介微调步骤数据准备模型选择训练方式效果评估模型部署大模型微调&#xff08;基于讯飞星辰Maas&#xff09;构建数据集方法1&#xff1a;预置数据集方法2&#xff1a;创建数据集数据辅助工具数据集划分模型微调数据配置参数配置模型部…