Java中使用Gson实现任意结构JSON配置的深度覆盖合并
Gson实现JSON配置深度覆盖合并方案
核心规则是仅覆盖环境配置中存在的字段,保留基础配置所有未被指定覆盖的字段,对嵌套JSON对象做递归合并,而非整节点替换。
合并逻辑规则
- 遍历环境配置的所有键值对,不处理环境配置中不存在的基础配置字段
- 若当前键在基础配置、环境配置中对应的值均为JSON对象,则递归合并两个嵌套对象
- 其余场景(值为基础类型/数组/布尔值/null、基础配置无对应键、两边值类型不匹配),直接使用环境配置的值覆盖对应字段
完整实现代码
import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.apache.commons.io.IOUtils; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Map; public class ConfigMergeUtil { /** * 深度合并两个JSON配置对象 * @param baseConfig 基础配置 * @param envConfig 环境专属覆盖配置 * @return 合并后的新配置对象,不会修改传入的原始配置对象 */ public static JsonObject merge(JsonObject baseConfig, JsonObject envConfig) { // 拷贝基础配置作为结果基底,避免修改原始对象 JsonObject result = baseConfig.deepCopy(); for (Map.Entry<String, JsonElement> entry : envConfig.entrySet()) { String configKey = entry.getKey(); JsonElement envValue = entry.getValue(); JsonElement baseValue = result.get(configKey); // 双对象场景递归合并 if (envValue.isJsonObject() && baseValue != null && baseValue.isJsonObject()) { JsonObject mergedNestedObj = merge(baseValue.getAsJsonObject(), envValue.getAsJsonObject()); result.add(configKey, mergedNestedObj); } else { // 其余场景直接覆盖,需要自定义数组合并、类型校验等逻辑可在此分支扩展 result.add(configKey, envValue.deepCopy()); } } return result; } // 调用示例 public static void main(String[] args) throws Exception { // 读取基础配置x.json,和你现有解析逻辑一致 InputStream baseStream = ConfigMergeUtil.class.getResourceAsStream("/x.json"); JsonObject base = JsonParser.parseString(IOUtils.toString(baseStream, StandardCharsets.UTF_8)).getAsJsonObject(); // 读取环境配置x_env.json InputStream envStream = ConfigMergeUtil.class.getResourceAsStream("/x_env.json"); JsonObject env = JsonParser.parseString(IOUtils.toString(envStream, StandardCharsets.UTF_8)).getAsJsonObject(); // 得到最终合并配置 JsonObject finalConfig = merge(base, env); } }
实现说明
- 代码基于你当前使用的Gson原生API实现,不需要引入额外依赖
- 支持任意层级的JSON嵌套结构,没有深度限制,适配任意结构的JSON配置
- 全程对原始配置对象做
deepCopy()处理,合并操作不会修改你之前解析得到的base、env原始Json对象,无副作用 - 默认数组类型值直接整段覆盖,如果需要做数组追加、去重等特殊合并,可以在else分支中添加对应判断逻辑
- 若环境配置中存在基础配置完全没有的新键,会自动新增到最终配置中;若同键两边类型不匹配,以环境配置的值为准
内容的提问来源于stack exchange,提问作者hello
相关产品推荐
相关产品推荐

