写一个支持多层级JSON字段差异比对,同事可以排除指定字段的java程序
时间: 2023-05-26 17:05:25 浏览: 62
以下是一个支持多层级JSON字段差异比对,同时可以排除指定字段的Java程序示例:
```java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.*;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.*;
public class JsonDiff {
public static Set<String> ignoreSet = new HashSet<>(); //要忽略的字段
/**
* 比较两个JSON字符串的差异
* @param json1 JSON字符串1
* @param json2 JSON字符串2
* @return 返回差异结果的JSON字符串
* @throws Exception
*/
public static String diff(String json1, String json2) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode node1 = mapper.readTree(json1);
JsonNode node2 = mapper.readTree(json2);
return diff(node1, node2).toString();
}
/**
* 比较两个JsonNode的差异
* @param node1 JsonNode1
* @param node2 JsonNode2
* @return 返回差异结果的JsonNode
*/
public static JsonNode diff(JsonNode node1, JsonNode node2) {
if (!node1.getNodeType().equals(node2.getNodeType())) {
return node2;
}
if (node1.isValueNode()) { //值节点
if (node1.equals(node2)) {
return null;
} else {
return node2;
}
}
if (node1.isArray()) { //数组
ArrayNode arrayNode1 = (ArrayNode) node1;
ArrayNode arrayNode2 = (ArrayNode) node2;
if (arrayNode1.size() != arrayNode2.size()) {
return arrayNode2;
}
JsonNode diff = null;
for (int i = 0; i < arrayNode1.size(); i++) {
JsonNode temp = diff(arrayNode1.get(i), arrayNode2.get(i));
if (temp != null && !temp.isNull()) {
if (diff == null) {
diff = arrayNode2.arrayNode();
}
((ArrayNode) diff).add(temp);
}
}
return diff;
}
ObjectNode objectNode1 = (ObjectNode) node1;
ObjectNode objectNode2 = (ObjectNode) node2;
// 比较差异
ObjectNode diff = objectNode2.objectNode();
Iterator<String> fieldNames = objectNode1.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (ignoreSet.contains(fieldName)) {
continue;
}
if (objectNode2.has(fieldName)) {
JsonNode diffNode = diff(objectNode1.get(fieldName), objectNode2.get(fieldName));
if (diffNode != null && !diffNode.isNull()) {
diff.set(fieldName, diffNode);
}
} else {
diff.set(fieldName, objectNode1.get(fieldName));
}
}
// 添加新增字段
fieldNames = objectNode2.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (ignoreSet.contains(fieldName)) {
continue;
}
if (!objectNode1.has(fieldName)) {
diff.set(fieldName, objectNode2.get(fieldName));
}
}
if (diff.size() == 0) {
return null;
}
return diff;
}
public static void main(String[] args) throws Exception {
String json1 = "{\"name\":\"tom\",\"age\":10,\"address\":{\"city\":\"beijing\",\"district\":\"haidian\"},\"hobbies\":[\"reading\",\"swimming\"]}";
String json2 = "{\"name\":\"jerry\",\"age\":11,\"address\":{\"city\":\"beijing\",\"district\":\"chaoyang\"},\"hobbies\":[\"reading\",\"playing football\"]}";
ignoreSet.add("name"); //排除name字段的比较
String diff = JsonDiff.diff(json1, json2);
System.out.println("差异结果:" + diff);
}
}
```
该程序使用了Jackson库来解析和比较JSON字符串和JsonNode,支持比较值节点、数组和对象节点的差异,并可以排除指定的字段进行比较。最终返回的是差异结果的JsonNode。在此基础上,可以将JsonNode转成字符串输出。