我有一个程序,可以比较两个响应主体,但我不知道主体是什么样子,所以我没有将它们反序列化为 Java 对象,而是将它们保留为 JsonNode 对象。假设我有以下两个 JsonNode 对象:
{
"name": "Bob",
"Age": 30,
"id": 1,
"status" : {
"active": "true",
"address": "123 Main St"
}
}
和
{
"name": "Bob",
"Age": 30,
"status" : {
"active": "true"
}
}
第二个 JsonNode 对象缺少
id
和 status.address
字段。但是,对于两个 JsonNode 对象存在的字段,它们是相等的。在比较它们时,我想忽略比较缺失的字段,而只比较两个 JsonNode 对象中存在的字段。同样,我无法将它们反序列化为对象并通过 Jackson 注释进行比较。所以我的限制是:
杰克逊有什么办法可以实现这一点吗?如果可以的话,有人可以指出它的文档吗?我认为我必须编写自己的比较器,但是任何现有的文献都会有所帮助。
JsonNode.equals(Comparator, JsonNode)
与自定义比较器一起使用。但由于您不关心排序,因此最好只进行相等性检查。下面的示例使用递归来深度优先检查节点。根据实际用例,您可能需要切换到广度优先算法。
public class CustomNodeComparator {
public static boolean customEquals(JsonNode node1, JsonNode node2) {
JsonNodeType node1Type = node1.getNodeType();
if (!node1Type.equals(node2.getNodeType())) {
//array and object are not equal
return false;
}
Iterator<String> names = node1.fieldNames();
while (names.hasNext()) {
String name = names.next();
JsonNode o2Node = node2.get(name);
if (o2Node == null) {
//assume equal, continue with other nodes
continue;
}
JsonNode o1Node = node1.get(name);
if (!o1Node.isValueNode()) {
return customEquals(o1Node, o2Node);
}
//compares everything as text
//depending on requirements you may need to compare taking value type into consideration
boolean isEqual = o1Node.asText().equals(o2Node.asText());
if (!isEqual) {
//end fast, no need to compare the rest
return false;
}
}
return true;
}
}
请注意,该示例没有考虑比较两个数组的可能性。
您可以尝试使用库 Josson & Jossons 按运算符比较两个 JSON 数据集:
左减右
<-<
或 >->
它也可以处理数组比较。
https://github.com/octomix/josson
Jossons jossons = new Jossons();
jossons.putDataset("json1", Josson.fromJsonString(
"{" +
" \"name\": \"Bob\"," +
" \"Age\": 30," +
" \"id\": 1," +
" \"status\" : {" +
" \"active\": \"true\"," +
" \"array1\": [1,2,3]," +
" \"array2\": [4,5]," +
" \"address\": \"123 Main St\"" +
" }" +
"}"));
jossons.putDataset("json2", Josson.fromJsonString(
"{" +
" \"name\": \"Bob\"," +
" \"Age\": 30," +
" \"status\" : {" +
" \"array1\": [3,2,1]," +
" \"array2\": [6,5]," +
" \"active\": \"true\"" +
" }" +
"}"));
System.out.println(jossons.evaluateQuery("json1 <-< json2").toPrettyString());
输出
{
"id" : 1,
"status" : {
"array2" : [ 4 ],
"address" : "123 Main St"
}
}