Java 如何在json比较中跳过节点
我有一个json比较器Java 如何在json比较中跳过节点,java,json,algorithm,Java,Json,Algorithm,我有一个json比较器 class JSONUtils { public static void areEqual(def context_1, def context_2) { Object obj1,obj2; Object json = new JSONTokener(context_1).nextValue(); if (json instanceof JSONObject) { obj1 = new JSONObject(context_1);
class JSONUtils {
public static void areEqual(def context_1, def context_2) {
Object obj1,obj2;
Object json = new JSONTokener(context_1).nextValue();
if (json instanceof JSONObject) {
obj1 = new JSONObject(context_1);
obj2 = new JSONObject(context_2);
} else if (json instanceof JSONArray) {
obj1 = new JSONArray(context_1);
obj2 = new JSONArray(context_2);
}
def ObjectMapper mapper = new ObjectMapper();
def JsonNode tree1 = mapper.readTree(obj1.toString());
def JsonNode tree2 = mapper.readTree(obj2.toString());
assert tree1.equals(tree2);
}
}
当两个json完全相同时,这可以正常工作。我有一个特例,在比较时需要跳过或忽略两个节点值
例如:
First Json:
{
"rd":12,
"td":"text1"
"dt": 123456,
"vt": "west"
}
Second Json:
{
"rd":12,
"td":"text1"
"dt": 333333,
"vt": "east"
}
我需要忽略或跳过“dt”和“vt”的比较
如何实现它。创建一个自定义POJO来保存您关心的值:
// Ignore fields "dt" and "vt"
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyType {
// Ideally these should use getters/setters
public int rd;
public String td;
@Override
public boolean equals(Object obj) {
if (obj instanceof MyType) {
MyType t = (MyType)obj;
return t.rd == this.rd
&& Objects.equals(t.td, this.td);
}
return false;
}
// hashCode() should always be overriden alongside equals()
@Override
public int hashCode() {
return Objects.hash(rd, td);
}
}
在代码中,您可以这样构造和比较它们:
ObjectMapper mapper = new ObjectMapper();
MyType t1 = mapper.readValue(obj1.toString(), MyType.class);
MyType t2 = mapper.readValue(obj2.toString(), MyType.class);
assert t1.equals(t2);
根据我们在评论中的讨论,这里有一个通用的解决方案,可以比较任意两个JSON对象,同时使用Guava库过滤掉任意一组键:
public static boolean jsonEquals(String json1, String json2, String... ignoreKeys) throws IOException {
// this is a Guava Predicate
Predicate<String> filter = Predicates.not(Predicates.in(Sets.newHashSet(ignoreKeys)));
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> object1 = Maps.filterKeys(mapper.readValue(json1, Map.class), filter);
Map<String, Object> object2 = Maps.filterKeys(mapper.readValue(json2, Map.class), filter);
return object1.equals(object2);
}
public静态布尔jsonEquals(字符串json1、字符串json2、字符串…ignoreKeys)抛出IOException{
//这是番石榴谓词
Predicate filter=Predicates.not(Predicates.in(Sets.newHashSet(ignoreKeys));
ObjectMapper mapper=新的ObjectMapper();
MapObject1=Maps.filterKeys(mapper.readValue(json1,Map.class),filter);
MapObject2=Maps.filterKeys(mapper.readValue(json2,Map.class),filter);
返回object1.equals(object2);
}
创建一个自定义POJO来保存您关心的值:
// Ignore fields "dt" and "vt"
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyType {
// Ideally these should use getters/setters
public int rd;
public String td;
@Override
public boolean equals(Object obj) {
if (obj instanceof MyType) {
MyType t = (MyType)obj;
return t.rd == this.rd
&& Objects.equals(t.td, this.td);
}
return false;
}
// hashCode() should always be overriden alongside equals()
@Override
public int hashCode() {
return Objects.hash(rd, td);
}
}
在代码中,您可以这样构造和比较它们:
ObjectMapper mapper = new ObjectMapper();
MyType t1 = mapper.readValue(obj1.toString(), MyType.class);
MyType t2 = mapper.readValue(obj2.toString(), MyType.class);
assert t1.equals(t2);
根据我们在评论中的讨论,这里有一个通用的解决方案,可以比较任意两个JSON对象,同时使用Guava库过滤掉任意一组键:
public static boolean jsonEquals(String json1, String json2, String... ignoreKeys) throws IOException {
// this is a Guava Predicate
Predicate<String> filter = Predicates.not(Predicates.in(Sets.newHashSet(ignoreKeys)));
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> object1 = Maps.filterKeys(mapper.readValue(json1, Map.class), filter);
Map<String, Object> object2 = Maps.filterKeys(mapper.readValue(json2, Map.class), filter);
return object1.equals(object2);
}
public静态布尔jsonEquals(字符串json1、字符串json2、字符串…ignoreKeys)抛出IOException{
//这是番石榴谓词
Predicate filter=Predicates.not(Predicates.in(Sets.newHashSet(ignoreKeys));
ObjectMapper mapper=新的ObjectMapper();
MapObject1=Maps.filterKeys(mapper.readValue(json1,Map.class),filter);
MapObject2=Maps.filterKeys(mapper.readValue(json2,Map.class),filter);
返回object1.equals(object2);
}
com.fasterxml.jackson.databind.JsonMappingException:com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)处的START_数组令牌无法反序列化com.dynatrace.groovysupport.MyType的实例at@AllIsWell[{“id”:23,“type”:1},{“id”:24,“type”:1}]
与您在问题中发布的内容完全不同。我正在尝试使用静态定义上下文3=“[{“type\”:1,\“id\”:23},{“type\”:1,\“id\”:24}]”静态定义上下文4=“[{“type\”:1,\“id\”:23},{“type\”:1,\“id\”:24}]";@AllIsWell我根据您问题中的JSON创建了类型。我不知道你想向我展示什么。@AllIsWell另外,你没有提到你在任何地方使用groovy.com.fasterxml.jackson.databind.JsonMappingException:无法反序列化com.dynatrace.groovysupport.MyType的实例,该实例位于[Source:[{“id”:23,“type”:1},{“id”:24,“type”:1}];第1行,第1列]位于com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)at@AllIsWell[{“id”:23,“type”:1},{“id”:24,“type”:1}]
与您在问题中发布的内容完全不同。我正在尝试此数据静态定义上下文3=“[{“type\”:1,\“id\”:23},{“type\”:1,\“id\”:24}”;静态定义上下文4=“[{\'type\':1,\'id\':23},{\'type\':1,\'id\':24}]”@AllIsWell我根据您问题中的JSON创建了类型。“我不知道你想向我展示什么。”AllIsWell还有,你没有提到你正在使用groovy的任何地方。