Java中的Json Path和Json Merge Patch


Java中的Json PatchJson Merge Patch都做得很好-一种表示对源json结构进行更改的方法。  Json Patch通过一系列转换源文档的操作来完成它,而Json Merge Patch将更改表示为源文档的精简版。
源文档:

{
  "title": "Goodbye!",
 
"author": {
   
"givenName": "John",
   
"familyName": "Doe"
  },
 
"tags": [
   
"example",
   
"sample"
  ],
 
"content": "This will be unchanged"
}

转换目标文档为:

{
  "title": "Hello!",
 
"author": {
   
"givenName": "John"
  },
 
"tags": [
   
"example"
  ],
 
"content": "This will be unchanged",
 
"phoneNumber": "+01-123-456-7890"
}

对比两种JSON文档,所作的合并的更改集为:
  1. title 被更改
  2. Author/familyName已删除
  3. tags之一被删除
  4. 添加 phone number

 
Json Patch

这种改变可以使用Json Patch 表达:
[
  { "op": "replace", "path": "/title", "value": "Hello!"},
  {
"op": "remove", "path": "/author/familyName"},
  {
"op": "add", "path": "/phoneNumber", "value": "+01-123-456-7890"},
  {
"op": "replace", "path": "/tags", "value": ["example"]}
]

通过上述一系列操作将源文档转换为目标文档。操作可以是“添加”,“删除”,“替换”,“移动”,“复制”或“测试”之一,并且在示例中与diff完全匹配。
 
Json Merge Patch
Json merge patch如下:
{
  "title": "Hello!",
 
"author": {
   
"familyName": null
  },
 
"phoneNumber": "+01-123-456-7890",
 
"tags": [
   
"example"
  ]
}

对于更改的应用方式需要一些解释,但非常直观:
  1. 存在带有新值的“ title”表示需要更改标题。
  2. 姓氏的显式“ null”表示应删除该字段。
  3.  phoneNumber字段表示需要添加新字段。
  4. 更新的标签表示需要修改标签。

 
在Java中使用Json Patch
json-patch是一个很棒的Java库,它同时支持Json Patch和Json Merge Patch。它与出色的Jackson库集成,并在库的顶部提供了补丁工具。该示例在kotlin中:
val s = """
{
   
"title": "Goodbye!",
   
"author": {
     
"givenName": "John",
     
"familyName": "Doe"
    },
   
"tags": [
     
"example",
     
"sample"
    ],
   
"content": "This will be unchanged"
}        
""".trimIndent()
 
 
val patch =
"""
    [
        {
"op": "replace", "path": "/title", "value": "Hello!"},
        {
"op": "remove", "path": "/author/familyName"},
        {
"op": "add", "path": "/phoneNumber", "value": "+01-123-456-7890"},
        {
"op": "replace", "path": "/tags", "value": ["example"]}
    ]
""".trimIndent()
val jsonPatch: JsonPatch = JsonPatch.fromJson(objectMapper.readTree(patch))
val target = jsonPatch.apply(objectMapper.readTree(s))

 
在Java中使用Json Merge Patch
该库使使用Json Merge补丁同样容易:
val s = """
{
   
"title": "Goodbye!",
   
"author": {
     
"givenName": "John",
     
"familyName": "Doe"
    },
   
"tags": [
     
"example",
     
"sample"
    ],
   
"content": "This will be unchanged"
}        
""".trimIndent()
 
 
val patch =
"""
{
   
"title": "Hello!",
   
"author": {
     
"familyName": null
    },
   
"phoneNumber": "+01-123-456-7890",
   
"tags": ["example"]
}   
""".trimIndent()
 
val jsonMergePatch: JsonMergePatch = JsonMergePatch.fromJson(objectMapper.readTree(patch))
val target = jsonMergePatch.apply(objectMapper.readTree(s))

 
结论
Json Patch和Json Merge Patch是表示对JSON文档所做的更改的方法。两种方法的执行方式略有不同,但都同样直观。