1.概述
将使用Jackson-Java的JSON处理库,比较两个JSON对象。
2.使用Jackson比较两个JSON对象
2.1比较两个简单的JSON对象
从使用JsonNode.equals方法开始。 equals()方法执行完整(深度)比较。
假设我们有一个定义为s1变量的JSON字符串:
json字符串1
{
"employee":
{
"id": "1212",
"fullName": "John Miles",
"age": 34
}
}
json字符串2
{
"employee":
{
"id": "1212",
"age": 34,
"fullName": "John Miles"
}
}
rivate static void test1() throws JsonProcessingException {
String json1 = "{ \"employee\": { \"id\": \"1212\", \"fullName\": \"John Miles\", \"age\": 34 }}";
String json2 = "{ \"employee\": { \"id\": \"1212\", \"age\": 34, \"fullName\": \"John Miles\" }}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
System.out.println(jsonNode1.equals(jsonNode2));//true
重要的是要注意,即使输入JSON变量json1和josn2中的属性顺序不相同,equals()方法也会忽略顺序并将它们视为相等。
2.2比较带有嵌套元素的两个JSON对象
json1
{
"employee":
{
"id": "1212",
"fullName":"John Miles",
"age": 34,
"contact":
{
"email": "[email protected]",
"phone": "9999999999"
}
}
}
json2
{
"employee":
{
"id": "1212",
"age": 34,
"fullName": "John Miles",
"contact":
{
"email": "[email protected]",
"phone": "9999999999"
}
}
}
String json1 = "{ \"employee\": { \"id\": \"1212\", \"fullName\":\"John Miles\", \"age\": 34, \"contact\": { \"email\": \"[email protected]\", \"phone\": \"9999999999\" } }}";
String json2 = "{\"employee\": { \"id\": \"1212\", \"age\": 34, \"fullName\": \"John Miles\", \"contact\": { \"email\": \"[email protected]\", \"phone\": \"9999999999\" } }}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
System.out.println(jsonNode1.equals(jsonNode2));//true
同样,应该注意到equals()也可以将两个输入的JSON对象与嵌套元素进行比较。
2.3比较两个包含列表元素的JSON对象
json1
{
"employee":
{
"id": "1212",
"fullName": "John Miles",
"age": 34,
"skills": ["Java", "C++", "Python"]
}
}
{
"employee":
{
"id": "1212",
"age": 34,
"fullName": "John Miles",
"skills": ["Java", "C++", "Python"]
}
}
String json1 = "{\"employee\":{\"id\":\"1212\",\"fullName\":\"John Miles\",\"age\":34,\"skills\":[\"Java\",\"C++\",\"Python\"]}}";
String json2 = "{\"employee\":{\"id\":\"1212\",\"age\":34,\"fullName\":\"John Miles\",\"skills\":[\"Java\",\"C++\",\"Python\"]}}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
System.out.println(jsonNode1.equals(jsonNode2));//true
重要的是要知道,两个列表元素只有在具有完全相同顺序的相同值时才被比较为相等。
3.使用自定义比较器比较两个JSON对象
在大多数情况下,JsonNode.equals都可以很好地工作。 Jackson还提供JsonNode.equals(comparator,JsonNode)来配置自定义Java Comparator对象。了解如何使用自定义比较器。
3.1自定义比较器以比较数值
json1
{
"name": "John",
"score": 5.0
}
json2
{
"name": "John",
"score": 5
}
String json1 = "{\"name\":\"John\",\"score\":5.0}";
String json2 = "{\"name\":\"John\",\"score\":5}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
System.out.println(jsonNode1.equals(jsonNode2));//false
首先,创建一个Comparator来比较两个NumericNode对象:
/**
* @author Created by niugang on 2021-03-26 17:47
*/
public class NumericNodeComparator implements Comparator<JsonNode>
{
@Override
public int compare(JsonNode o1, JsonNode o2)
{
if (o1.equals(o2)){
return 0;
}
if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)){
Double d1 = o1.asDouble();
Double d2 = o2.asDouble();
if (d1.compareTo(d2) == 0) {
return 0;
}
}
return 1;
}
}
String json1 = "{\"name\":\"John\",\"score\":5.0}";
String json2 = "{\"name\":\"John\",\"score\":5}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
NumericNodeComparator cmp = new NumericNodeComparator();
System.out.println(jsonNode1.equals(cmp,jsonNode2));//true
3.2自定义比较器以比较文本值
json1
{
"name": "john",
"score": 5
}
json2
{
"name": "JOHN",
"score": 5
}
String json1 = "{\"name\":\"john\",\"score\":5}";
String json2 = "{\"name\":\"JOHN\",\"score\":5}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
System.out.println(jsonNode1.equals(jsonNode2));//false
创建一个Comparator来比较两个TextNode对象:
public class TextNodeComparator implements Comparator<JsonNode>
{
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) {
String s1 = o1.asText();
String s2 = o2.asText();
if (s1.equalsIgnoreCase(s2)) {
return 0;
}
}
return 1;
}
}
private static void test5() throws JsonProcessingException {
String json1 = "{\"name\":\"john\",\"score\":5}";
String json2 = "{\"name\":\"JOHN\",\"score\":5}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode1 = objectMapper.readTree(json1);
JsonNode jsonNode2 = objectMapper.readTree(json2);
TextNodeComparator textNodeComparator = new TextNodeComparator();
System.out.println(jsonNode1.equals(textNodeComparator,jsonNode2));//true
}