kotlin中实现json更新处理、json合并处理、最终返回一个完整的 JSON 字符串

现在的 mergeDetailed 返回的是更新后的 Bean 对象,但你想要的是:将 JSON 数据合并到另一个 JSON 中,有就更新,没有就添加,最终返回一个完整的 JSON 字符串

也就是说,你需要一个 JsonObject 级别的合并工具,而不是先转成 Bean 再转回来。


方案:直接合并两个 JSON 字符串

kotlin 复制代码
package com.gzyq.ynlk.util

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser

object JsonMergeUtil {

    val gson = Gson()

    /**
     * 将 sourceJson 合并到 targetJson 中
     * - targetJson 中存在的字段:用 sourceJson 的值覆盖
     * - targetJson 中不存在的字段:从 sourceJson 添加进来
     * - 返回合并后的完整 JSON 字符串
     */
    fun mergeJson(targetJson: String, sourceJson: String): String {
        val target = JsonParser.parseString(targetJson).asJsonObject
        val source = JsonParser.parseString(sourceJson).asJsonObject

        source.entrySet().forEach { (key, value) ->
            target.add(key, value)
        }

        return gson.toJson(target)
    }

    /**
     * 带详细信息的版本,返回合并后的 JSON 字符串 + 变更信息
     */
    fun mergeJsonDetailed(targetJson: String, sourceJson: String): JsonMergeResult {
        val target = JsonParser.parseString(targetJson).asJsonObject
        val source = JsonParser.parseString(sourceJson).asJsonObject

        val targetFields = target.keySet().toList()
        val sourceFields = source.keySet().toList()

        // 记录合并前的值
        val beforeMap = target.toValueMap()

        // 执行合并:source 覆盖/添加到 target
        source.entrySet().forEach { (key, value) ->
            target.add(key, value)
        }

        val afterMap = target.toValueMap()

        // 分析变更
        val updatedFields = sourceFields.filter { key ->
            key in targetFields && beforeMap[key] != afterMap[key]
        }
        val addedFields = sourceFields.filter { it !in targetFields }
        val unchangedFields = sourceFields.filter { key ->
            key in targetFields && beforeMap[key] == afterMap[key]
        }

        return JsonMergeResult(
            mergedJson = gson.toJson(target),
            updatedFields = updatedFields,      // 被修改的字段
            addedFields = addedFields,          // 新增的字段
            unchangedFields = unchangedFields,  // 值未变的字段
            sourceFields = sourceFields,
            targetFields = targetFields
        )
    }

    private fun JsonObject.toValueMap(): Map<String, String> {
        val map = mutableMapOf<String, String>()
        this.entrySet().forEach { (key, element) ->
            map[key] = element.toString()
        }
        return map
    }
}

// 返回结构体
data class JsonMergeResult(
    val mergedJson: String,           // 合并后的完整 JSON 字符串
    val updatedFields: List<String>,   // 被更新的字段(target 中已存在且值变了)
    val addedFields: List<String>,     // 新增的字段(target 中原来没有)
    val unchangedFields: List<String>, // 值未变的字段
    val sourceFields: List<String>,    // source 中的所有字段
    val targetFields: List<String>     // target 中的所有字段
)

使用示例

kotlin 复制代码
fun main() {
    val targetJson = """{"id":1,"user_name":"张三","user_age":25,"email":"test@qq.com"}"""
    val sourceJson = """{"user_name":"李四","user_age":25,"phone":"13800138000","address":"北京"}"""

    val result = JsonMergeUtil.mergeJsonDetailed(targetJson, sourceJson)

    println("合并后的 JSON:")
    println(result.mergedJson)
    // {"id":1,"user_name":"李四","user_age":25,"email":"test@qq.com","phone":"13800138000","address":"北京"}

    println("更新的字段:${result.updatedFields}")      // [user_name]
    println("新增的字段:${result.addedFields}")          // [phone, address]
    println("未变的字段:${result.unchangedFields}")      // [user_age]
}

对比你原来的用法

你的需求 原来的 mergeDetailed 新的 mergeJsonDetailed
输入 Bean + JSON 字符串 JSON 字符串 + JSON 字符串
输出 MergeResult<T>(Bean 对象) JsonMergeResult(JSON 字符串)
适用场景 需要拿到 Bean 对象做后续业务处理 只需要合并 JSON,不关心具体 Bean 类型

如果你还需要保留原来的 Bean 合并功能,可以把两个方法共存,按需使用。

相关推荐
bugcome_com20 分钟前
JWT 知识小课堂:从入门到精通,一文吃透 JSON Web Token
前端·json
pengyu6 小时前
【Kotlin 协程修仙录 · 元婴境 · 中阶】 | 操作符真解:Flow 中间操作符与数据流变幻术
android·kotlin
pengyu7 小时前
【Kotlin 协程修仙录 · 元婴境 · 初阶】 | 冷流初啼:Flow 的基础与响应式编程的入门
android·kotlin
ccino .15 小时前
awvs_json_word.py 使用说明手册
json·word
richard_yuu15 小时前
JSON vs XML vs 二进制:3种序列化终极选型
xml·c++·qt·学习·json
Kapaseker1 天前
破坏性更新 - 解读 Jetpack Compose 1.12
android·kotlin
用户7783366132111 天前
SERP 返回 JSON 用 Pydantic 强校验:类型安全解析
json
Android-Flutter1 天前
android LeakCanary 工作原理 详解
android·kotlin
Android-Flutter1 天前
android 自定义view 详解
android·kotlin
Android打工仔1 天前
从 finally 理解程序的控制流:它为什么不是 catch 后面的代码?
android·kotlin