我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
当前回答
下面的代码将更有助于比较两个JsonObject, JsonArray, JsonPrimitive和JasonElements。
private boolean compareJson(JsonElement json1, JsonElement json2) {
boolean isEqual = true;
// Check whether both jsonElement are not null
if (json1 != null && json2 != null) {
// Check whether both jsonElement are objects
if (json1.isJsonObject() && json2.isJsonObject()) {
Set<Entry<String, JsonElement>> ens1 = ((JsonObject) json1).entrySet();
Set<Entry<String, JsonElement>> ens2 = ((JsonObject) json2).entrySet();
JsonObject json2obj = (JsonObject) json2;
if (ens1 != null && ens2 != null) {
// (ens2.size() == ens1.size())
// Iterate JSON Elements with Key values
for (Entry<String, JsonElement> en : ens1) {
isEqual = isEqual && compareJson(en.getValue(), json2obj.get(en.getKey()));
}
} else {
return false;
}
}
// Check whether both jsonElement are arrays
else if (json1.isJsonArray() && json2.isJsonArray()) {
JsonArray jarr1 = json1.getAsJsonArray();
JsonArray jarr2 = json2.getAsJsonArray();
if (jarr1.size() != jarr2.size()) {
return false;
} else {
int i = 0;
// Iterate JSON Array to JSON Elements
for (JsonElement je : jarr1) {
isEqual = isEqual && compareJson(je, jarr2.get(i));
i++;
}
}
}
// Check whether both jsonElement are null
else if (json1.isJsonNull() && json2.isJsonNull()) {
return true;
}
// Check whether both jsonElement are primitives
else if (json1.isJsonPrimitive() && json2.isJsonPrimitive()) {
if (json1.equals(json2)) {
return true;
} else {
return false;
}
} else {
return false;
}
} else if (json1 == null && json2 == null) {
return true;
} else {
return false;
}
return isEqual;
}
其他回答
org。我已经推出了自己的解决方案,一个与JSONObject实例进行比较的方法。我在那个项目中没有使用复杂的JSON对象,所以我不知道这是否适用于所有场景。此外,鉴于我在单元测试中使用了这个功能,我没有在优化方面投入精力。下面就是:
public static boolean jsonObjsAreEqual (JSONObject js1, JSONObject js2) throws JSONException {
if (js1 == null || js2 == null) {
return (js1 == js2);
}
List<String> l1 = Arrays.asList(JSONObject.getNames(js1));
Collections.sort(l1);
List<String> l2 = Arrays.asList(JSONObject.getNames(js2));
Collections.sort(l2);
if (!l1.equals(l2)) {
return false;
}
for (String key : l1) {
Object val1 = js1.get(key);
Object val2 = js2.get(key);
if (val1 instanceof JSONObject) {
if (!(val2 instanceof JSONObject)) {
return false;
}
if (!jsonObjsAreEqual((JSONObject)val1, (JSONObject)val2)) {
return false;
}
}
if (val1 == null) {
if (val2 != null) {
return false;
}
} else if (!val1.equals(val2)) {
return false;
}
}
return true;
}
我做的一件事是将两个对象读入HashMap,然后与常规的assertEquals()进行比较。它将调用哈希映射的equals()方法,该方法将递归地比较其中的所有对象(它们将是其他哈希映射或一些单值对象,如字符串或整数)。这是使用Codehaus的Jackson JSON解析器完成的。
assertEquals(mapper.readValue(expectedJson, new TypeReference<HashMap<String, Object>>(){}), mapper.readValue(actualJson, new TypeReference<HashMap<String, Object>>(){}));
如果JSON对象是一个数组,则可以使用类似的方法。
你可以尝试使用json-lib的JSONAssert类:
JSONAssert.assertEquals(
"{foo: 'bar', baz: 'qux'}",
JSONObject.fromObject("{foo: 'bar', baz: 'xyzzy'}")
);
给:
junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>
要比较json,我建议使用我的JSONCompare库: https://github.com/fslev/json-compare
// Compare by regex
String expected = "{\"a\":\".*me.*\"}";
String actual = "{\"a\":\"some text\"}";
JSONCompare.assertEquals(expected, actual); // True
// Check expected array has no extra elements
String expected = "[1,\"test\",4,\"!.*\"]";
String actual = "[4,1,\"test\"]";
JSONCompare.assertEquals(expected, actual); // True
// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[\"text\",\"test\"]";
JSONCompare.assertEquals(expected, actual); // True
// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[2018]";
JSONCompare.assertNotEquals(expected, actual); // True
查看答案,我尝试了JSONAssert,但失败了。所以我用Jackson和zjsonpatch。我在SO的答案中发布了详细信息。