Java中的Json Path和Json Merge Patch

banq發表於2021-05-13

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文件所做的更改的方法。兩種方法的執行方式略有不同,但都同樣直觀。

相關文章