在 Java 中比较两个 JSON 文件的最佳方法

问题描述 投票:0回答:12

您建议如何完成这项任务?

我认为挑战在于智能地呈现差异信息。在我重新发明轮子之前,是否有一种公认的方法来处理这种比较?

java json comparison
12个回答
33
投票

我推荐zjsonpatch库,它根据RFC 6902(JSON补丁)提供差异信息。 您可以与 Jackson 一起使用它:

import com.fasterxml.jackson.databind.{ObjectMapper, JsonNode}
JsonNode beforeNode = jacksonObjectMapper.readTree(beforeJsonString);
JsonNode afterNode = jacksonObjectMapper.readTree(afterJsonString);

import com.flipkart.zjsonpatch.JsonDiff
JsonNode patch = JsonDiff.asJson(beforeNode, afterNode);
String diffs = patch.toString();

这个库比 fge-json-patch(在另一个答案中提到)更好,因为它可以检测从数组中插入/删除的项目。 Fge-json-patch 无法处理这个问题(如果将一个项目插入到数组的中间,它会认为该项目以及之后的每个项目都已更改,因为它们都移了一位)。


19
投票

我在 JSONAssert 方面取得了很好的经验。

import org.junit.Test;
import org.apache.commons.io.FileUtils;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;

... 
@Test
public void myTest() {
  String expectedJson = FileUtils.readFileToString("/expectedFile");
  String actualJson = FileUtils.readFileToString("/actualFile");
  JSONAssert.assertEquals(expectedJson, actualJson, JSONCompareMode.STRICT);
}
... 

16
投票

比较 json 字符串的最简单方法是使用

JSONAssert
库中的 JSONCompare。优点是,它不仅限于结构,如果您愿意,还可以比较值:

JSONCompareResult result = 
     JSONCompare.compareJSON(json1, json2, JSONCompareMode.STRICT);
System.out.println(result.toString());

它将输出类似以下内容:

Expected: VALUE1
     got: VALUE2
 ; field1.field2

13
投票

这仅解决平等问题,而不解决差异问题。


和杰克逊一起。

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(jsonInput1);
JsonNode tree2 = mapper.readTree(jsonInput2);

boolean areTheyEqual = tree1.equals(tree2);

来自 JsonNode.equals 的 JavaDoc:

节点对象的相等被定义为完全(深度)值相等。这意味着可以通过比较根节点的相等性来比较完整的 JSON 树的相等性。


5
投票
您可以尝试

XStream的架构,处理JSON映射

另外,请查看这篇文章:

比较两个 XML 文件并使用 C# 中的 XMLDiff 生成第三个文件。虽然是 C# 语言,但逻辑是一样的。


4
投票
我遇到了类似的问题,最终编写了自己的库:

https://github.com/algesten/jsondiff

它可以进行差异/修补。

Diff 本身就是 JSON 对象,并且具有用于对象合并/替换和数组插入/替换的简单语法。

示例:

original { a: { b: 42 } } patch { "~a": { c: 43 } }

~

表示对象合并。

result { a: { b: 42, c: 43 } }
    

2
投票
您可以使用下面的依赖关系将 Json 与 STRICT、LENIENT、IGNORE_ORDER 等进行比较

<dependency> <groupId>org.skyscreamer</groupId> <artifactId>jsonassert</artifactId> <version>1.5.0</version> <scope>test</scope> </dependency>

public static boolean isTwoJsonEquals(JSONObject firstObj,JSONObject secondObj, JSONCompareMode compareMode){ try { JSONCompareResult result = JSONCompare.compareJSON(firstObj, secondObj, compareMode); return result.passed(); } catch (JSONException e) { e.printStackTrace(); } return false; }

    

1
投票
json-lib

我要做的是使用

json-lib 解析 json 数据。这将产生常规的 java 对象,您可以使用 equals 方法进行比较。这仅在假设来自 json-lib 的人正确实现了 equals 方法时才有效,但您可以轻松测试。


1
投票
对于已经在使用

Jackson 的人,我推荐 json-patch

final JsonNode patchNode = JsonDiff.asJson(firstNode, secondNode); System.out.println("Diff=" + m.writeValueAsString(patchNode));
    

0
投票
如果想要比较两个 JSON 忽略元素/对象的顺序,看看这个

library 是否可以帮助你。

用途:

List<Diff> diff = new DnjsonDiff().getDiff(String left, String right) Left =[{"name":"Bob","businessKey":"4444"},{"name":"John","businessKey":"5555"}] Right = [{"name":"Bob","businessKey":"6666"},{"name":"John", "businessKey":"4444"}] Diff: [ { "op": "replace", "configuredValue": "John", "intendedValue": "Bob", "businessKey": "4444" }, { "op": "remove", "configuredValue": null, "intendedValue": "{\"name\":\"John\",\"businessKey\":\"5555\"}", "businessKey": "5555" }, { "op": "add", "configuredValue": "{\"name\":\"Bob\",\"businessKey\":\"6666\"}", "intendedValue": null, "businessKey": "null" } ]
    

0
投票
使用

Google 的 Guava 库进行比较。检查这个答案,其中详细解释了如何使用它。

https://stackoverflow.com/a/50969020/17762303


-1
投票
Junit5 已经支持比较两个 json 对象以及内容检查。

ObjectMapper mapper = new ObjectMapper(); String json1 = {"key" : "value"}; // from file String json2 = {"key" : "value"}; // Assert that two JSONs are equal, ignoring the order of elements JSONAssert.assertEquals(json1, json2, JSONCompareMode.LENIENT);
    
© www.soinside.com 2019 - 2024. All rights reserved.