现在的 mergeDetailed 返回的是更新后的 Bean 对象,但你想要的是:将 JSON 数据合并到另一个 JSON 中,有就更新,没有就添加,最终返回一个完整的 JSON 字符串。
也就是说,你需要一个 JsonObject 级别的合并工具,而不是先转成 Bean 再转回来。
方案:直接合并两个 JSON 字符串
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 中的所有字段
)
使用示例
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 合并功能,可以把两个方法共存,按需使用。
728

被折叠的 条评论
为什么被折叠?



