Java中的Json Patch和Json 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文档,所作的合并的更改集为:
- title 被更改
- Author/familyName已删除
- tags之一被删除
- 添加 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" ] }
|
对于更改的应用方式需要一些解释,但非常直观:
- 存在带有新值的“ title”表示需要更改标题。
- 姓氏的显式“ null”表示应删除该字段。
- phoneNumber字段表示需要添加新字段。
- 更新的标签表示需要修改标签。
在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文档所做的更改的方法。两种方法的执行方式略有不同,但都同样直观。