You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中JSON差异存储与默认JSON合并实现问询

Spring Boot 复杂JSON差异生成、保存与合并实现方案

一、依赖配置

首先在pom.xml中添加Jackson相关依赖,确保版本与Spring Boot自带的Jackson版本对齐:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jsonpatch</artifactId>
    <version>2.15.2</version> <!-- 版本需匹配Spring Boot的Jackson版本 -->
</dependency>

二、生成JsonPatch并保存差异

读取默认JSON与modifiedDefault JSON,转换为JsonNode后生成差异Patch,再序列化为JSON文件保存:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonpatch.JsonPatch;
import com.fasterxml.jackson.module.jsonpatch.JsonPatchGenerator;

import java.io.File;
import java.io.IOException;

public class JsonPatchService {
    private final ObjectMapper objectMapper = new ObjectMapper();

    // 生成差异Patch并保存到文件
    public void generateAndSavePatch(File defaultJsonFile, File modifiedJsonFile, File patchOutputFile) throws IOException {
        // 读取两个JSON文件为JsonNode
        JsonNode defaultNode = objectMapper.readTree(defaultJsonFile);
        JsonNode modifiedNode = objectMapper.readTree(modifiedJsonFile);

        // 生成从默认到修改后的JsonPatch
        JsonPatchGenerator patchGenerator = new JsonPatchGenerator(defaultNode);
        JsonPatch patch = patchGenerator.generatePatch(modifiedNode);

        // 将Patch序列化为格式化JSON并保存
        objectMapper.writerWithDefaultPrettyPrinter().writeValue(patchOutputFile, patch);
    }
}

三、合并默认JSON与修改内容

提供两种合并方式,按需选择:

方式1:应用保存的JsonPatch到默认JSON

如果已保存Patch文件,直接读取并应用到默认JSON:

public JsonNode mergeDefaultWithPatch(File defaultJsonFile, File patchFile) throws IOException {
    JsonNode defaultNode = objectMapper.readTree(defaultJsonFile);
    JsonPatch patch = objectMapper.readValue(patchFile, JsonPatch.class);

    // 应用Patch生成合并结果
    return patch.apply(defaultNode);
}

方式2:直接递归合并modifiedDefault与默认JSON

针对modifiedDefault覆盖默认值的场景,自定义递归逻辑处理嵌套结构与数组:

// 递归合并:modifiedNode字段覆盖defaultNode对应字段
public JsonNode mergeJsonNodes(JsonNode defaultNode, JsonNode modifiedNode) {
    if (modifiedNode.isObject()) {
        JsonNode merged = defaultNode.deepCopy();
        modifiedNode.fields().forEachRemaining(entry -> {
            String key = entry.getKey();
            JsonNode modifiedValue = entry.getValue();
            JsonNode defaultValue = merged.get(key);
            // 嵌套对象递归合并,其他类型直接替换
            if (defaultValue != null && defaultValue.isContainerNode() && modifiedValue.isContainerNode()) {
                merged = merged.set(key, mergeJsonNodes(defaultValue, modifiedValue));
            } else {
                merged = merged.set(key, modifiedValue);
            }
        });
        return merged;
    } else if (modifiedNode.isArray()) {
        // 数组直接替换(如需部分元素修改,可自定义数组差异逻辑)
        return modifiedNode.deepCopy();
    } else {
        // 基础类型直接替换
        return modifiedNode;
    }
}

// 合并方法调用入口
public JsonNode mergeDefaultWithModified(File defaultJsonFile, File modifiedJsonFile) throws IOException {
    JsonNode defaultNode = objectMapper.readTree(defaultJsonFile);
    JsonNode modifiedNode = objectMapper.readTree(modifiedJsonFile);
    return mergeJsonNodes(defaultNode, modifiedNode);
}

四、Spring Boot Controller整合

在GET接口中调用合并逻辑返回结果:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.File;
import java.io.IOException;

@RestController
public class JsonMergeController {
    private final JsonPatchService patchService = new JsonPatchService();

    @GetMapping("/merged-config")
    public JsonNode getMergedConfig() throws IOException {
        File defaultFile = new File("src/main/resources/default.json");
        File modifiedFile = new File("src/main/resources/modifiedDefault.json");
        
        // 可选:用Patch文件合并的方式
        // File patchFile = new File("src/main/resources/config-patch.json");
        // return patchService.mergeDefaultWithPatch(defaultFile, patchFile);
        
        return patchService.mergeDefaultWithModified(defaultFile, modifiedFile);
    }
}

关键注意事项

  • 数组处理:默认JsonPatch会生成数组元素级操作(如add/remove/replace),若需完全替换数组,直接使用递归合并更简便;若需精确修改数组元素,优先用JsonPatch。
  • 依赖版本:确保jackson-module-jsonpatch版本与Spring Boot自带的Jackson版本一致,避免依赖冲突。
  • 文件读取:实际项目中建议通过ResourceLoader读取classpath下的资源文件,而非硬编码路径。

内容的提问来源于stack exchange,提问作者Harsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:10:28