2016-08-01 12 views
0

Ich habe einen json Komparatorwie ein Knoten in json Vergleich überspringen

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); 
    } 
} 

der gut arbeitet, wenn zwei json genau gleich sind. Ich habe einen speziellen Fall, wo ich zwei Knotenwerte während des Vergleichs überspringen oder ignorieren muss.

Beispiel:

First Json: 
{ 
    "rd":12, 
    "td":"text1" 
    "dt": 123456, 
    "vt": "west" 
} 
Second Json: 
{ 
    "rd":12, 
    "td":"text1" 
    "dt": 333333, 
    "vt": "east" 
} 

Ich brauche die "dt" und "vt" Vergleich zu ignorieren oder überspringen.

Wie kann ich es implementieren.

Antwort

2

Erstellen eines benutzerdefinierten POJO, um die Werte halten Sie kümmern uns um:

// 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); 
    } 
} 

In Ihrem Code können Sie konstruieren und vergleichen sie wie folgt aus:

ObjectMapper mapper = new ObjectMapper(); 
MyType t1 = mapper.readValue(obj1.toString(), MyType.class); 
MyType t2 = mapper.readValue(obj2.toString(), MyType.class); 
assert t1.equals(t2); 

Per unserer Diskussion in der Kommentare, hier ist eine generische Lösung, um zwei beliebige JSON-Objekte zu vergleichen, während alle Schlüssel unter Verwendung der Guava-Bibliothek herausgefiltert werden:

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); 
} 
+0

com.fasterxml.jackson.databind.JsonMappingException: Kann nicht deserialisieren Instanz com.dynatrace.groovysupport.MyType aus START_ARRAY Token bei [Quelle: [{ "id": 23, "type": 1}, {"id": 24, "Typ": 1}]; Linie: 1, Säule: 1] \t bei com.fasterxml.jackson.databind.JsonMappingException.from (JsonMappingException.java:148) \t bei – ChanChow

+0

@AllIsWell '[{ "id": 23, "type": 1} , {"id": 24, "type": 1}] 'ist nichts wie das, was Sie in der Frage gepostet haben. – shmosel

+0

Ich probiere für diese Daten aus \t static def context_3 = "[{" type \ ": 1, \" id \ ": 23}, {\ type \": 1, \ "id \": 24} ] "; \t static def context_4 = "[{" Typ \ ": 1, \" ID \ ": 23}, {\" Typ \ ": 1, \" ID \ ": 24}]"; – ChanChow