高效处理 JSON 数据:JsonUtil 工具类全方位解析与实战

在现代软件开发中,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,返回0
    return 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 (superClass != null) {
        for (Field field : superClass.getDeclaredFields()) {
            if (field.getName().equals(targetFieldName)) {
                field.setAccessible(true);
                return field.get(object);
            }
        }
    }
    return null;
}

使用示例

// 定义用户类(含敏感字段)
class User {
    private Long id;
    private String name;
    private String password; // 敏感字段,需隐藏
    // getter/setter
}

// 创建用户对象
User user = new User();
user.setId(1L);
user.setName("张三");
user.setPassword("123456");

// 仅保留"id"和"name"字段,生成JSON
String userJson = JsonUtil.objectToStringIncludeArrays(user, new String[]{"id", "name"});
// 输出:{"id":1,"name":"张三"}(无password字段)

4. 内容替换(replaceStringInJson):递归遍历JSON

业务场景:日志系统中,所有JSON格式的日志需将“旧域名(old.com)”替换为“新域名(new.com)”,包括嵌套在深层的字段(如{"ext":{"url":"http://old.com/path"}})。

方法作用:递归遍历JSON的所有字段(包括嵌套JSONObjectJSONArray),批量替换字符串内容。

源码核心逻辑

// 入口方法:JSON字符串替换
public static String replaceStringInJson(String jsonString, String oldString, String newString) {
    try {
        JSONObject json = JSON.parseObject(jsonString);
        replaceStringInJson(json, oldString, newString); // 调用递归方法
        return json.toString();
    } catch (JSONException e) {
        logger.error("JSON替换失败", e);
        return jsonString; // 失败时返回原始字符串,避免业务中断
    }
}

// 递归方法:处理JSONObject和JSONArray
private static void replaceStringInJson(Object object, String oldString, String newString) {
    if (object instanceof JSONObject) {
        // 处理JSONObject:遍历所有key
        JSONObject json = (JSONObject) object;
        for (String key : json.keySet()) {
            Object value = json.get(key);
            if (value instanceof String) {
                // 字符串类型:直接替换
                String newValue = ((String) value).replaceAll(oldString, newString);
                json.put(key, newValue);
            } else {
                // 非字符串:递归处理(可能是JSONObject/JSONArray)
                replaceStringInJson(value, oldString, newString);
            }
        }
    } else if (object instanceof JSONArray) {
        // 处理JSONArray:遍历所有元素
        JSONArray jsonArray = (JSONArray) object;
        for (Object item : jsonArray) {
            replaceStringInJson(item, oldString, newString); // 递归处理元素
        }
    }
}

使用示例

String jsonStr = "{" +
    "\"name\":\"旧文本示例\"," +
    "\"ext\":{\"desc\":\"旧文本需要替换\"}," +
    "\"tags\":[{\"label\":\"旧标签\"}]" +
"}";

// 将所有"旧"替换为"新"
String newJson = JsonUtil.replaceStringInJson(jsonStr, "旧", "新");
// 输出结果:
// {
//   "name":"新文本示例",
//   "ext":{"desc":"新文本需要替换"},
//   "tags":[{"label":"新标签"}]
// }

三、实战场景:从业务需求到工具应用

场景1:微服务数据合并(jsonMerge

需求:电商商品详情页需整合3个接口数据:

  • 基础接口:{"id":1,"name":"手机","price":3999}
  • 库存接口:{"id":1,"stock":100,"warehouse":"北京仓"}
  • 促销接口:{"id":1,"discount":0.9,"activity":"限时折扣"}

实现步骤

  1. 调用3个接口,获取返回的JSON数据;
  2. 以基础接口数据为target,依次合并库存、促销接口数据;
  3. 返回合并后的完整商品信息。

代码示例

// 模拟接口返回数据
JSONObject baseJson = JSON.parseObject("{\"id\":1,\"name\":\"手机\",\"price\":3999}");
JSONObject stockJson = JSON.parseObject("{\"id\":1,\"stock\":100,\"warehouse\":\"北京仓\"}");
JSONObject promotionJson = JSON.parseObject("{\"id\":1,\"discount\":0.9,\"activity\":\"限时折扣\"}");

// 合并数据:基础信息 → 合并库存 → 合并促销
JSONObject productJson = JsonUtil.jsonMerge(stockJson, baseJson);
productJson = JsonUtil.jsonMerge(promotionJson, productJson);

// 输出合并结果
// {
//   "id":1,
//   "name":"手机",
//   "price":3999,
//   "stock":100,
//   "warehouse":"北京仓",
//   "discount":0.9,
//   "activity":"限时折扣"
// }

场景2:敏感字段过滤(listToStringIncludeArrays

需求:用户管理接口返回用户列表时,仅展示“id”“username”“role”字段,隐藏“password”“email”等敏感信息。

实现步骤

  1. 从数据库查询用户列表(含所有字段);
  2. 使用listToStringIncludeArrays过滤字段,生成仅含指定字段的JSON;
  3. 返回过滤后的JSON给前端。

代码示例

// 模拟数据库查询结果
List<User> userList = new ArrayList<>();
userList.add(new User(1L, "zhangsan", "123456", "zhangsan@old.com", "admin"));
userList.add(new User(2L, "lisi", "654321", "lisi@old.com", "user"));

// 仅保留"id"、"username"、"role"字段
String userListJson = JsonUtil.listToStringIncludeArrays(userList, new String[]{"id", "username", "role"});
// 输出:
// [
//   {"id":1,"username":"zhangsan","role":"admin"},
//   {"id":2,"username":"lisi","role":"user"}
// ]

场景3:日志内容替换(replaceStringInJson

需求:所有JSON格式的操作日志中,需将用户手机号(如“13800138000”)中间4位替换为“****”,保护隐私。

实现步骤

  1. 日志生成时,获取原始JSON日志字符串;
  2. 使用正则表达式匹配手机号,调用replaceStringInJson替换;
  3. 输出处理后的日志。

代码示例

// 原始日志(含手机号)
String logJson = "{" +
    "\"operate\":\"login\"," +
    "\"user\":{\"name\":\"张三\",\"phone\":\"13800138000\"}," +
    "\"ext\":{\"device\":\"phone\",\"contact\":\"13900139000\"}" +
"}";

// 替换手机号中间4位(使用正则:(\d{3})\d{4}(\d{4}) → $1****$2)
String maskedLog = JsonUtil.replaceStringInJson(logJson, "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
// 输出结果:
// {
//   "operate":"login",
//   "user":{"name":"张三","phone":"138****8000"},
//   "ext":{"device":"phone","contact":"139****9000"}
// }

四、JsonUtil的优势:对比原生框架

处理场景原生FastJSON/JacksonJsonUtil工具类
JSON合并需要手动遍历字段,递归处理嵌套结构(约20行代码)一行代码调用jsonMerge,自动处理嵌套
安全提取字段需手动判断null(如json!=null?json.getString(key):""直接调用getString,内置空值处理
字段过滤需手动创建Map,逐个put字段(约10行代码)一行代码指定字段,反射自动提取
内容替换需手动递归遍历JSON,处理数组和嵌套对象一行代码调用replaceStringInJson,自动递归
异常处理需手动捕获JSONException,编写日志逻辑内置异常处理,自动记录日志并兜底

五、扩展建议与注意事项

1. 扩展方向

  • 支持JSONPath:添加getByJsonPath方法(如通过$.user.name直接获取嵌套字段),提升复杂JSON的提取效率。
  • 超大JSON处理:针对100MB+的JSON,改用流式解析(如Jackson的JsonParser),避免一次性加载到内存导致OOM。
  • 类型转换增强:支持日期格式自定义(如yyyy-MM-dd),解决JSON中日期字段默认格式(时间戳)不直观的问题。

2. 注意事项

  • 序列化依赖:深拷贝和合并功能依赖对象可序列化(若处理自定义对象,需确保其实现Serializable接口)。
  • 数组长度限制jsonMerge方法要求合并的JSONArray长度一致,若需支持不同长度,可修改源码去除校验(需注意索引越界风险)。
  • 性能考量:反射和递归操作(如objectToStringIncludeArraysreplaceStringInJson)对超大对象有性能损耗,高频场景建议缓存结果。

六、源代码

代码示例

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonParser;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @ClassName: JsonUtil
 * @Description: JSON操作工具类
 * @Version 1.0
 */
public class JsonUtil {

    private static final Logger logger = LogManager.getLogger(JsonUtil.class);

    /**
     * 合并JSON对象,用source覆盖target,返回覆盖后的JSON对象
     */
    public static JSONObject jsonMerge(JSONObject source, JSONObject target) {
        // 参数校验
        if (source == null) {
            logger.error("参数source为空,返回target数据!");
            return target;
        }
        if (target == null) {
            logger.error("参数target为空,返回source数据!");
            return source;
        }
        try {
            for (String key : source.keySet()) {
                Object value = source.get(key);
                // 如果target中不包含该key,直接添加
                if (!target.containsKey(key)) {
                    target.put(key, value);
                    continue;
                }
                // 如果值为JSONObject类型,递归合并
                if (value instanceof JSONObject) {
                    JSONObject sourceValue = (JSONObject) value;
                    JSONObject targetValue = target.getJSONObject(key);
                    JSONObject mergedValue = jsonMerge(sourceValue, targetValue);
                    target.put(key, mergedValue);
                    continue;
                }
                // 如果值为JSONArray类型,遍历数组进行合并
                if (value instanceof JSONArray) {
                    JSONArray sourceArray = (JSONArray) value;
                    JSONArray targetArray = target.getJSONArray(key);
                    // 确保两个数组长度一致
                    if (sourceArray.size() != targetArray.size()) {
                        throw new IllegalArgumentException("Arrays have different lengths for key: " + 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) {
                            JSONObject mergedItem = jsonMerge((JSONObject) sourceItem, (JSONObject) targetItem);
                            targetArray.set(i, mergedItem);
                        }
                    }
                    continue;
                }
                // 其他类型直接覆盖
                target.put(key, value);
            }
        } catch (Exception e) {
            // 记录错误日志
            logger.error("JSON merge error", e);
            // 可以考虑使用日志框架,如:logger.error("JSON merge error", e);
            throw new RuntimeException("Error merging JSON objects", e);
        }
        return target;
    }

    /**
     * 合并两个JSONArray,将array2的元素追加到array1的元素之后。
     *
     * @param array1 第一个JSONArray,优先保留
     * @param array2 第二个JSONArray,将被追加到array1之后
     * @return 合并后的新JSONArray,包含两个数组的所有元素
     * @throws IllegalArgumentException 如果两个数组中存在非JSONObject元素
     * @throws RuntimeException         如果合并过程中发生错误
     */
    public static JSONArray jsonArrayMerge(JSONArray array1, JSONArray array2) {
        // 参数校验
        if (array1 == null) {
            logger.error("参数array1为空,返回array2数据!");
            return array2;
        }
        if (array2 == null) {
            logger.error("参数array2为空,返回array1数据!");
            return array1;
        }
        JSONArray mergedArray = new JSONArray();
        try {
            // 添加第一个数组的所有元素
            addAllSafe(array1, mergedArray);
            // 添加第二个数组的所有元素
            addAllSafe(array2, mergedArray);
        } catch (Exception e) {
            // 记录错误日志
            logger.error("JSON array merge error", e);
            // 可以考虑使用日志框架,如:logger.error("JSON array merge error", e);
            throw new RuntimeException("Error merging JSON arrays", e);
        }
        return mergedArray;
    }

    /**
     * 深度复制一个JSONObject。
     *
     * @param source 要复制的JSONObject
     * @return 深度复制后的JSONObject
     */
    private static JSONObject deepCopy(JSONObject source) {
        return JSON.parseObject(JSON.toJSONString(source));
    }


    /**
     * 安全地将源数组的所有元素添加到目标数组。
     *
     * @param source 源JSONArray
     * @param target 目标JSONArray
     */
    private static void addAllSafe(JSONArray source, JSONArray target) {
        for (Object item : source) {
            // 检查元素类型,确保为JSONObject类型
            if (item instanceof JSONObject) {
                target.add(deepCopy((JSONObject) item));
            } else if (item instanceof JSONArray) {
                // 如果需要支持嵌套数组,可以递归处理
                JSONArray nestedArray = new JSONArray();
                addAllSafe((JSONArray) item, nestedArray);
                target.add(nestedArray);
            } else {
                // 非对象元素直接添加
                target.add(item);
            }
        }
    }



    public static JSONObject toJsonObject(String jsonString) {
        return JSONObject.parseObject(jsonString);
    }

    /**
     * 将json字符串转换为T
     */
    public static <T> T fromJsonStringToT(String jsonString, Class<T> clazz) {
        return JSONObject.parseObject(jsonString, clazz);
    }

    /**
     * 将Object转换为字符串
     */
    public static String toString(Object object) {
        return JSONObject.toJSONString(object);
    }


    /**
     * list对象转换为Json字符串,仅包含arrays中的属性值
     */
    public static String listToStringIncludeArrays(List<?> list, String[] arrays) {
        List<Object> result = new ArrayList<>();
        for (Object object : list) {
            Map<String, Object> map = objectToMapIncludeArrays(object, arrays);
            result.add(map);
        }
        return JSONObject.toJSONString(result);
    }

    /**
     * Object对象转换为json字符串,仅包含arrays中的属性值
     */
    public static String objectToStringIncludeArrays(Object object, String[] arrays) {
        Map<String, Object> result = objectToMapIncludeArrays(object, arrays);
        return JSONObject.toJSONString(result);
    }


    private static Map<String, Object> objectToMapIncludeArrays(Object object, String[] arrays) {
        Map<String, Object> result = new HashMap<>();
        for (String array : arrays) {
            // 如果需要转换的为Map对象,则直接从map中包含arrays的值放到新的map中
            if (object instanceof Map) {
                result.put(array, ((Map<?, ?>) object).get(array));
            } else {
                // 如果非map则从object中通过反射获取属性值,放到map中
                try {
                    Object value = getFieldValueByObject(object, array);
                    result.put(array, value);
                } catch (Exception e) {
                    System.out.println(e.toString());
                }
            }
        }
        return result;
    }

    private static Object getFieldValueByObject(Object object, String targetFieldName) throws Exception {
        // 获取该对象的Class
        Class<?> objClass = object.getClass();
        // 获取所有的属性数组
        Field[] fields = objClass.getDeclaredFields();
        for (Field field : fields) {
            // 属性名称
            String currentFieldName = field.getName();
            if (currentFieldName.equals(targetFieldName)) {
                field.setAccessible(true);
                // 通过反射拿到该属性在此对象中的值(也可能是个对象)
                return field.get(object);
            }
        }
        // 获取继承类里面的属性值
        Class<?> superClass = objClass.getSuperclass();
        if (null != superClass) {
            Field[] superFields = superClass.getDeclaredFields();
            for (Field superField : superFields) {
                // 属性名称
                String currentFieldName = superField.getName();
                if (currentFieldName.equals(targetFieldName)) {
                    superField.setAccessible(true);
                    // 通过反射拿到该属性在此对象中的值(也可能是个对象)
                    return superField.get(object);
                }
            }
        }
        return null;
    }

    /**
     * 判断是否jsonObj或者jsonArray格式字符串
     */
    public static boolean isJsonStr(String jsonStr) {
        try {
            JSON.parse(jsonStr);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 用gson判断字符串是否是有效的Json串
     */
    public static boolean isGsonStr(String jsonStr) {
        try {
            JsonParser.parseString(jsonStr);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 将json字符串转为map
     */
    public static Map<String, Object> jsonToMap(String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> map = null;
        try {
            map = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {
            });
        } catch (JsonProcessingException e) {
            logger.error("jsonToMap error: {}", e.getMessage());
            throw new RuntimeException("Json To Map Error: " + e.getMessage());
        }
        return map;
    }

    /**
     * json格式字符串转换为List的map
     */
    public static List<Map<String, Object>> jsonToList(String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        List<Map<String, Object>> list = null;
        try {
            list = objectMapper.readValue(json, new TypeReference<List<Map<String, Object>>>() {
            });
        } catch (JsonProcessingException e) {
            System.err.println(e.getMessage());
        }
        return list;
    }

    /**
     * *将json字符串转换为对象集合
     *
     * @param jsonString json字符串
     * @param valueType  对象类型
     **/
    public static <T> List<T> jsonToList(String jsonString, Class<T> valueType) throws IOException {
        if (StringUtils.isBlank(jsonString)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(jsonString, objectMapper.getTypeFactory().constructCollectionType(List.class, valueType));
    }

    /**
     * 获取JSONObject中指定字段的字符串值
     *
     * @param jsonObject JSONObject对象
     * @param key        字段名
     * @return 字段对应的字符串值,若字段不存在则返回空字符串
     */
    public static String getString(JSONObject jsonObject, String key) {
        return Objects.nonNull(jsonObject.getString(key)) ? jsonObject.getString(key) : "";
    }

    /**
     * 获取JSONObject中指定字段的整数值
     *
     * @param jsonObject JSONObject对象
     * @param key        字段名
     * @return 字段对应的整数值,若字段不存在或无法转换为整数时返回0
     */
    public static int getInt(JSONObject jsonObject, String key) {
        return Objects.nonNull(jsonObject.getInteger(key)) ? jsonObject.getInteger(key) : 0;
    }

    /**
     * 获取JSONObject中指定字段的布尔值
     *
     * @param jsonObject JSONObject对象
     * @param key        字段名
     * @return 字段对应的布尔值,若字段不存在或无法转换为布尔值时返回false
     */
    public static boolean getBoolean(JSONObject jsonObject, String key) {
        return Objects.nonNull(jsonObject.getBoolean(key)) ? jsonObject.getBoolean(key) : false;
    }

    /**
     * 获取JSONObject中指定字段的JSONObject对象
     *
     * @param jsonObject JSONObject对象
     * @param key        字段名
     * @return 字段对应的JSONObject对象,若字段不存在或无法转换为JSONObject对象时返回null
     */
    public static JSONObject getJsonObject(JSONObject jsonObject, String key) {
        return Objects.nonNull(jsonObject.getJSONObject(key)) ? jsonObject.getJSONObject(key) : null;
    }

    /**
     * 获取JSONObject中指定字段的JSONArray对象
     *
     * @param jsonObject JSONObject对象
     * @param key        字段名
     * @return 字段对应的JSONArray对象,若字段不存在或无法转换为JSONArray对象时返回null
     */
    public static JSONArray getJsonArray(JSONObject jsonObject, String key) {
        return Objects.nonNull(jsonObject.getJSONArray(key)) ? jsonObject.getJSONArray(key) : null;
    }

    /**
     * 将对象转换为JSONObject对象
     *
     * @param obj 对象
     * @return 转换后的JSONObject对象
     */
    public static JSONObject objectToJson(Object obj) {
        return JSON.parseObject(JSON.toJSONString(obj));
    }

    /**
     * 将JSON字符串转换为JSONArray对象
     *
     * @param json JSON字符串
     * @return 转换后的JSONArray对象,若转换失败则返回null
     */
    public static JSONArray stringToJsonArray(String json) {
        try {
            return JSON.parseArray(json);
        } catch (Exception e) {
            logger.error("String To JsonArray error: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 将JSONArray对象转换为JSON字符串
     *
     * @param jsonArray JSONArray对象
     * @return 转换后的JSON字符串
     */
    public static String jsonArrayToString(JSONArray jsonArray) {
        return jsonArray.toString();
    }

    /**
     * 将JSONArray对象转换为指定类型的List集合
     *
     * @param jsonArray JSONArray对象
     * @param clazz     List集合的元素类型
     * @return 转换后的List集合
     */
    public static <T> List<T> jsonArrayToList(JSONArray jsonArray, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            T item = null;
            try {
                item = clazz.newInstance();
                if (item instanceof JSONObject) {
                    list.add((T) jsonArray.getJSONObject(i));
                } else {
                    list.add((T) jsonArray.get(i));
                }
            } catch (Exception e) {
                logger.error("jsonArrayToList error: {}", e.getMessage());
                throw new RuntimeException("JsonArray To List Error: " + e.getMessage());
            }
        }
        return list;
    }

    /**
     * 将List集合转换为JSONArray对象
     *
     * @param list List集合
     * @return 转换后的JSONArray对象
     */
    public static JSONArray listToJsonArray(List<?> list) {
        JSONArray jsonArray = new JSONArray();
        for (Object obj : list) {
            jsonArray.add(objectToJson(obj));
        }
        return jsonArray;
    }

    /**
     * *将json字符串中的旧字符串替换成新字符串
     *
     * @param jsonString json字符串
     * @param oldString  旧字符串
     * @param newString  新字符串
     **/
    public static String replaceStringInJson(String jsonString, String oldString, String newString) {
        try {
            // 将json字符串转换为JSONObject对象
            JSONObject json = JSON.parseObject(jsonString);
            // 使用递归函数进行替换
            replaceStringInJson(json, oldString, newString);
            // 返回更新后的json字符串
            return json.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        // 如果发生异常,则返回原始的json字符串
        return jsonString;
    }

    /**
     * *将json对象中的旧字符串替换成新字符串
     *
     * @param object    JSONObject或JSONArray
     * @param oldString 旧字符串
     * @param newString 新字符串
     **/
    public static void replaceStringInJson(Object object, String oldString, String newString) {
        if (object instanceof JSONObject) {
            JSONObject json = (JSONObject) object;
            // 遍历JSONObject的所有键
            for (String key : json.keySet()) {
                Object value = json.get(key);
                // 如果键对应的值是字符串类型,则尝试替换旧字符串为新字符串
                if (value instanceof String) {
                    String oldValue = (String) value;
                    String newValue = oldValue.replaceAll(oldString, newString);
                    // 更新键对应的值为新字符串
                    json.put(key, newValue);
                } else {
                    replaceStringInJson(value, oldString, newString);
                }
            }
        } else if (object instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) object;
            for (Object value : jsonArray) {
                replaceStringInJson(value, oldString, newString);
            }
        }
    }
}

七、总结

JsonUtil工具类通过封装高频操作、处理边界情况、简化API调用,将开发者从重复的JSON处理代码中解放出来。无论是简单的格式转换,还是复杂的多源数据合并,都能通过一两行代码快速实现,且内置的空值处理、异常兜底机制大幅降低了线上故障风险。

在实际项目中,建议将JsonUtil作为基础工具类集成,结合业务场景扩展功能(如添加敏感字段自动过滤规则)。掌握这款工具,不仅能提升开发效率,更能培养“封装复用”的编程思维——将重复工作抽象为工具,是进阶高级开发的关键能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FinkGO小码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值