जावा में बाल आदेश की अनदेखी समानता के लिए दो JSON वस्तुओं का परीक्षण


233

मैं एक JSON पार्सिंग लाइब्रेरी की तलाश कर रहा हूं जो बाल आदेश की अनदेखी करने वाले दो JSON ऑब्जेक्ट्स की तुलना करने का समर्थन करती है, विशेष रूप से एक वेब सेवा से लौटने वाले JSON के यूनिट परीक्षण के लिए।

क्या कोई प्रमुख JSON लाइब्रेरी इसका समर्थन करती है? Org.json पुस्तकालय केवल एक संदर्भ तुलना करता है।


1
स्ट्रिंग को प्रतिनिधित्व और तुलना करने के लिए दोनों वस्तुओं को अनुक्रमित नहीं किया जा सकता है? मुझे लगता है कि सभी लाइब्रेरीज़ toString()ऑब्जेक्ट को JSONस्ट्रिंग में बदलने के लिए समर्थन करती हैं ।
तेजा कंतमनेनी

47
उस क्रम को क्रमबद्धता के आधार पर और तारों से हमेशा समान माना जाता है। मैं उस धारणा को बनाने में सहज नहीं हूं।
जेफ

आप सही जेफ हैं, यह बिल्कुल भी सुरक्षित नहीं है। यह परीक्षण एक परिदृश्य दिखाता है जहां मैपिंग समान हैं लेकिन स्ट्रिंग () एक ही आउटपुट नहीं लौटाता है: gist.github.com/anonymous/5974797 । इसका कारण यह है कि अंतर्निहित हैशपॉप विकसित हो सकता है, और यदि आप चाबियाँ निकालते हैं, तो हैशपॉइंट आंतरिक सरणी सिकुड़ती नहीं है।
गिलाउम पेरोट

जवाबों:


84

एक सामान्य वास्तुशिल्प बिंदु के रूप में, मैं आमतौर पर एक विशेष क्रमांकन प्रारूप पर निर्भरता देने के खिलाफ सलाह देता हूं जो आपके भंडारण / नेटवर्किंग परत से परे खून बह रहा है; इस प्रकार, मैं सबसे पहले सुझाव दूंगा कि आप अपने JSON अभिव्यक्तियों के बजाय अपने स्वयं के एप्लिकेशन ऑब्जेक्ट्स के बीच समानता का परीक्षण करने पर विचार करें।

यह कहने के बाद कि, मैं वर्तमान में जैक्सन का बहुत बड़ा प्रशंसक हूं, जो कि उनके ऑब्जेक्टनोडेक्लेस () के कार्यान्वयन के बारे में मेरी त्वरित जानकारी है, जो आपको चाहिए कि सेट सदस्यता तुलना करता है:

public boolean equals(Object o)
{
    if (o == this) return true;
    if (o == null) return false;
    if (o.getClass() != getClass()) {
        return false;
    }
    ObjectNode other = (ObjectNode) o;
    if (other.size() != size()) {
        return false;
    }
    if (_children != null) {
        for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
            String key = en.getKey();
            JsonNode value = en.getValue();

            JsonNode otherValue = other.get(key);

            if (otherValue == null || !otherValue.equals(value)) {
                return false;
            }
        }
    }
    return true;
}

यह विधि सममित नहीं है, क्योंकि यह केवल बच्चों के 'सबसेट' रिश्ते का परीक्षण करती है, समानता की नहीं। 'अन्य' ऑब्जेक्ट में फिर से अधिक बच्चे हो सकते हैं, और फिर यह तरीका सही होगा।
योनी

23
@ योनी: सच नहीं है, क्योंकि आकार की तुलना है। उनके पास ठीक उसी संख्या में बच्चे होने चाहिए, जैसे बच्चों के लिए। @ जॉली रोजर: इस मामले में, मैं JSON से वस्तु को POJO में वापस अनुक्रमित नहीं कर रहा हूं, लेकिन JSON को एक सिस्टम भेज रहा है जो करता है, मैं उस पर उसी तरह से वापस भेजने पर भरोसा नहीं कर सकता जिसमें मैंने भेजा था यह।
जेफ

1
@ जेफ यह काम आपके लिए किया था? कनिष्ठ में, मुखरता मेरे लिए विफल हो जाती है। परियोजना एक पुराने संस्करण (1.5), फी का उपयोग कर रही है।
रौनीफ़्म

1
मुझे लगता है कि यदि आप JSON पर जोर नहीं दे रहे हैं तो आपको कुछ उच्च स्तरीय परीक्षण याद आ रहे हैं। आपके पास एक पतली परीक्षा हो सकती है जो http अनुरोध करती है और कुछ अपेक्षित JSON के साथ प्रतिक्रिया करती है - यह वेब सेवा का मुख्य कार्यात्मक व्यवहार है।
मोग्रोनॉल

प्रदर्शन के संबंध में बस एक मामूली नोट: कोड जो 'value' की तुलना 'otherValue' से करता है, यदि (value.equals (other.get) (कुंजी)) गलत है, तो इसे सरल बनाया जा सकता है, क्योंकि 'value' शून्य नहीं होने की गारंटी है; JsonNode की बराबरी () विधि को एक अशक्त तर्क को स्वीकार करना चाहिए।
Tillmann

154

Skyscreamer के प्रयास करें JSONAssert

इसके गैर-सख्त मोड के दो प्रमुख फायदे हैं जो इसे कम भंगुर बनाते हैं:

  • ऑब्जेक्ट एक्स्टेंसिबिलिटी (जैसे {id: 1} के अपेक्षित मान के साथ , यह अभी भी पास होगा: {id: 1, moredata: 'x'} ।)
  • ढीला सरणी क्रम (जैसे ['कुत्ता', 'बिल्ली'] == ['बिल्ली', 'कुत्ता'])

सख्त मोड में यह अधिक व्यवहार करता है जैसे कि json-lib का परीक्षण वर्ग।

एक परीक्षण कुछ इस तरह दिखता है:

@Test
public void testGetFriends() {
    JSONObject data = getRESTData("/friends/367.json");
    String expected = "{friends:[{id:123,name:\"Corby Page\"}"
        + ",{id:456,name:\"Solomon Duskis\"}]}";
    JSONAssert.assertEquals(expected, data, false);
}

JSONAssert.assertEquals में पैरामीटर () कॉल कर रहे हैं expectedJSONString , actualDataString , और isStrict

परिणाम संदेश बहुत स्पष्ट हैं, जो वास्तव में बड़ी JSON ऑब्जेक्ट्स की तुलना करते समय महत्वपूर्ण है।


18
मैं इस समाधान का उपयोग कर रहा हूं, लेकिन मैंने अभी-अभी पाया है कि आप अपने चयन का JSONCompareMode भी प्रदान कर सकते हैं। जिनमें से एक NON_EXTENSIBLE है। तो आपके पास कुछ इस तरह का होगा: JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);NON_EXTENSIBLE मोड का मतलब है कि कोई भी नया या अनुपलब्ध फ़ील्ड विफलताओं का कारण बनता है, लेकिन ऑर्डर नहीं करता है। असत्य का उपयोग करने से उदार मोड उत्पन्न होगा जो किसी भी अतिरिक्त या लापता बाल तत्वों की रिपोर्ट नहीं करेगा।
दान मंदिर

1
NON_EXTENSIBLE तुलना मोड बिल्कुल वही है जो मैं देख रहा था। इसके लिए धन्यवाद, डैन।
थॉटक्राइम

इससे पहले कि मैं सभी उत्साहित हो जाऊं: क्या यह समर्थन JSON ऑब्जेक्ट्स और सरणियों को भी नेस्टेड करता है? :)
क्रिश्चियन

2
लाइब्रेरी का उपयोग करने से पहले लोग इस JSONassert मुद्दे को ध्यान में रखना चाहते हैं : यह इंगित करता है कि वर्तमान में लायब्रेरी की निर्भरता के साथ संभावित लाइसेंसिंग समस्याएँ हैं।
Chriki

3
JSONAssert ने PR 67 में क्लीन-रूम लाइब्रेरी रिप्लेसमेंट के साथ # 44 तय किया, आज JSONAssert 1.4.0 के रूप में जारी किया गया।
कार्टर पेज

49

GSON का उपयोग करना

JsonParser parser = new JsonParser();
JsonElement o1 = parser.parse("{a : {a : 2}, b : 2}");
JsonElement o2 = parser.parse("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

संपादित करें: चूंकि GSON v2.8.6 आवृत्ति विधि JsonParser.parseपदावनत है। आपको स्थैतिक विधि का उपयोग करना होगा JsonParser.parseString:

JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

मेरे लिए GSON 2.8.2 में काम करता है।
टॉम सालेबा

1
अगर jsonArray तत्व क्रम में नहीं हैं तो यह काम नहीं कर रहा है। संस्करण 2.8.2
नवीन कुमार आरबी

1
यदि वस्तु / तत्व का क्रम भिन्न हो तो मेरे लिए काम नहीं करना
Jknair

इसने मेरे लिए काम किया क्योंकि मैं इसे सिर्फ एक यूनिट टेस्ट के लिए चाहता था, जहां दो जेन्सन संपत्तियों का एक ही क्रम था
गेब्रियलबीबी

@GabrielBB आपको प्रश्न को संपादित करना चाहिए और यह बताना चाहिए कि एपीआई किस संस्करण में है और किस संस्करण में कोड की नई शैली काम करने लगती है।
clearlight

30

मैं निम्नलिखित कार्य करूंगा,

JSONObject obj1 = /*json*/;
JSONObject obj2 = /*json*/;

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(obj1.toString());
JsonNode tree2 = mapper.readTree(obj2.toString());

return tree1.equals(tree2);

यदि आप पहले से ही जैक्सन का उपयोग कर रहे हैं तो यह सबसे अच्छा उत्तर IMHO है।
क्रिस्टोफ़ डाइटेज़

18
लेकिन मुझे लगता है कि यह एक सख्त तुलना है। यह तत्वों के अलग-अलग क्रम वाले दो समान जौन के लिए गलत वापस आएगा।
डेडपूल

@ डेडपूल सिद्धांत ध्वनि है, आपको बस अधिक शामिल होने की तुलना बदलने की आवश्यकता होगी (उदाहरण के लिए कुंजी फ़ील्ड की जाँच करना, पेड़ों के एक साधारण बराबरी के बजाय)।
jwenting

यह अब तक का सबसे अच्छा जवाब है। न केवल यह मेरे प्रश्न का उत्तर देता है, क्योंकि यह लगभग हर वस्तु की तुलना का भी जवाब देता है जो हमें करने की आवश्यकता है। धन्यवाद, जोशु
लुइज़ फ़िजाओ वेरोनी

2
@ डेडपूल, यह एक सख्त तुलना हो सकती है, लेकिन यह अब सख्त नहीं है।
आंद्रेई डैमियन-फ़ेकेट

18

आप json-lib के JSONAssert वर्ग का उपयोग करने का प्रयास कर सकते हैं :

JSONAssert.assertEquals(
  "{foo: 'bar', baz: 'qux'}",
  JSONObject.fromObject("{foo: 'bar', baz: 'xyzzy'}")
);

देता है:

junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>

या इससे भी सरल: JSONAssert.assertJsonEquals ("{foo: 'bar', baz: 'qux'}", {foo: 'bar', baz: 'xyzzy'} ");
Rob Juurlink

2
यह समाधान JSON के भीतर डेटा आइटम के क्रम के लिए काम करता है, यह विफल हो जाएगा यदि सरणियों के भीतर तत्वों का क्रम मेल नहीं खाता है। यदि आपका कोड उदाहरण के लिए JSON में परिवर्तित एक सेट का उपयोग करता है। निम्नलिखित JSON तुलना विफल हो जाएगी: JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }"); संदेश के साथ:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Dan मंदिर

हां, यह Json :( की एक सीमा है :(। Json.org से पता चलता है कि कोई अनियंत्रित संग्रह टोकन नहीं है। {} केवल कुंजी-मूल्य जोड़े को घेर सकता है। यह बहुत ही परेशान करने वाला है
Merk

15

इस लाइब्रेरी का उपयोग करें: https://github.com/lukas-krecan/JsonUnit

पोम:

<dependency>
    <groupId>net.javacrumbs.json-unit</groupId>
    <artifactId>json-unit</artifactId>
    <version>1.5.0</version>
    <scope>test</scope>
</dependency>

IGNORING_ARRAY_ORDER - सरणियों में आदेश की उपेक्षा करता है

assertJsonEquals("{\"test\":[1,2,3]}",
  "{\"test\":  [3,2,1]}",
  when(IGNORING_ARRAY_ORDER)
);

क्या आप अधिक टिप्पणी जोड़ सकते हैं कि हम इसका उपयोग कैसे कर सकते हैं मैं इसे अपने पोम में जोड़ सकता हूं लेकिन हमें यह समझने के लिए डॉक्टर की आवश्यकता है कि इसका उपयोग कैसे किया जाए
Ran Adler

सुनिश्चित करें कि उपयोग बहुत सरल है: इसे अपने पोम में जोड़ें। <निर्भरता> <groupId> net.javacrumbs.json-unit </ groupId> <विरूपण साक्ष्य> json-unit </ विरूपण साक्ष्य> <संस्करण> 1.5.0 </ संस्करण> <गुंजाइश> परीक्षण </ गुंजाइश> </ निर्भरता>
chethu

10x मैंने लिंक पर दिए गए निर्देश को देखा है और मैंने इसे पाया :)
रैन एडलर

12

यदि आप पहले से ही JUnit का उपयोग कर रहे हैं, तो नवीनतम संस्करण अब Hamcrest को नियोजित करता है। यह एक सामान्य मैचिंग फ्रेमवर्क (विशेष रूप से यूनिट परीक्षण के लिए उपयोगी) है जिसे नए मैचर्स बनाने के लिए बढ़ाया जा सकता है।

एक छोटा सा ओपन सोर्स लाइब्रेरी है जिसे hamcrest-jsonJSON-जागरूक मैचों के साथ कहा जाता है । यह अच्छी तरह से प्रलेखित, परीक्षण और समर्थित है। नीचे कुछ उपयोगी लिंक दिए गए हैं:

JSON लाइब्रेरी से ऑब्जेक्ट का उपयोग करके उदाहरण कोड org.json.simple:

Assert.assertThat(
    jsonObject1.toJSONString(),
    SameJSONAs.sameJSONAs(jsonObject2.toJSONString()));

वैकल्पिक रूप से, आप (1) "किसी भी आदेश" सरणियों की अनुमति दे सकते हैं और (2) अतिरिक्त क्षेत्रों को अनदेखा कर सकते हैं।

चूंकि जावा ( Jacksonऔर GSON, json-libआदि) के लिए JSON लाइब्रेरी की एक किस्म है , यह उपयोगी है कि hamcrest-jsonJSON टेक्स्ट (एस java.lang.String), साथ ही साथ डगलस क्रॉकफोर्ड के JSON लाइब्रेरी से मूल रूप से सहायक वस्तुओं का समर्थन करता है org.json

अंत में, यदि आप JUnit का उपयोग नहीं कर रहे हैं, तो आप सीधे दावा के लिए Hamcrest का उपयोग कर सकते हैं। ( मैंने इसके बारे में यहां लिखा था। )


सीधे JSONAssert का उपयोग करने के बजाय हैमस्ट्रक मिलान करने वालों का उपयोग करने का क्या फायदा है?
जोहान्स

2
@ जोहान्स: स्टाइल ही।
केविनर्पपे

हैमरेस्ट-जोंस स्रोतों में वर्तमान में 2012 की अंतिम तारीख है। यह अब और अच्छी तरह से समर्थित नहीं हो सकता है।
थोरबजोरन राव एंडरसन

11

आप JsonUnit की कोशिश कर सकते हैं । यह दो JSON ऑब्जेक्ट्स की तुलना कर सकता है और अंतर रिपोर्ट कर सकता है। यह जैक्सन के ऊपर बनाया गया है।

उदाहरण के लिए

assertJsonEquals("{\"test\":1}", "{\n\"test\": 2\n}");

का परिणाम

java.lang.AssertionError: JSON documents are different:
Different value found in node "test". Expected 1, got 2.

6

एक चीज जो मैंने की थी और यह काम करता है कि चमत्कार दोनों वस्तुओं को हैशपॉप में पढ़ना है और फिर एक नियमित अभिकथन () के साथ तुलना करना है। यह हैशमैप्स के बराबर () विधि को कॉल करेगा, जो अंदर की सभी वस्तुओं की पुनरावर्ती रूप से तुलना करेगा (वे या तो अन्य हैशमैप होंगे या स्ट्रिंग या पूर्णांक की तरह कुछ एकल मान ऑब्जेक्ट)। यह Codehaus 'जैक्सन JSON पार्सर का उपयोग करके किया गया था।

assertEquals(mapper.readValue(expectedJson, new TypeReference<HashMap<String, Object>>(){}), mapper.readValue(actualJson, new TypeReference<HashMap<String, Object>>(){}));

एक समान दृष्टिकोण का उपयोग किया जा सकता है यदि JSON ऑब्जेक्ट इसके बजाय एक सरणी है।


6

मैं इसका उपयोग कर रहा हूं, और मेरे लिए ठीक काम करता है (org.json। * के साथ):

package com.project1.helpers;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class JSONUtils {

    public static boolean areEqual(Object ob1, Object ob2) throws JSONException {
        Object obj1Converted = convertJsonElement(ob1);
        Object obj2Converted = convertJsonElement(ob2);
        return obj1Converted.equals(obj2Converted);
    }

    private static Object convertJsonElement(Object elem) throws JSONException {
        if (elem instanceof JSONObject) {
            JSONObject obj = (JSONObject) elem;
            Iterator<String> keys = obj.keys();
            Map<String, Object> jsonMap = new HashMap<>();
            while (keys.hasNext()) {
                String key = keys.next();
                jsonMap.put(key, convertJsonElement(obj.get(key)));
            }
            return jsonMap;
        } else if (elem instanceof JSONArray) {
            JSONArray arr = (JSONArray) elem;
            Set<Object> jsonSet = new HashSet<>();
            for (int i = 0; i < arr.length(); i++) {
                jsonSet.add(convertJsonElement(arr.get(i)));
            }
            return jsonSet;
        } else {
            return elem;
        }
    }
}

4

Org.json के लिए मैंने अपना समाधान निकाला है, एक विधि जो JSONObject उदाहरणों की तुलना करती है। मैंने उस परियोजना में जटिल JSON ऑब्जेक्ट्स के साथ काम नहीं किया, इसलिए मुझे नहीं पता कि यह सभी परिदृश्यों में काम करता है या नहीं। इसके अलावा, यह देखते हुए कि मैं इसे यूनिट परीक्षणों में उपयोग करता हूं, मैंने प्रयास को अनुकूलन में नहीं रखा। यह रहा:

public static boolean jsonObjsAreEqual (JSONObject js1, JSONObject js2) throws JSONException {
    if (js1 == null || js2 == null) {
        return (js1 == js2);
    }

    List<String> l1 =  Arrays.asList(JSONObject.getNames(js1));
    Collections.sort(l1);
    List<String> l2 =  Arrays.asList(JSONObject.getNames(js2));
    Collections.sort(l2);
    if (!l1.equals(l2)) {
        return false;
    }
    for (String key : l1) {
        Object val1 = js1.get(key);
        Object val2 = js2.get(key);
        if (val1 instanceof JSONObject) {
            if (!(val2 instanceof JSONObject)) {
                return false;
            }
            if (!jsonObjsAreEqual((JSONObject)val1, (JSONObject)val2)) {
                return false;
            }
        }

        if (val1 == null) {
            if (val2 != null) {
                return false;
            }
        }  else if (!val1.equals(val2)) {
            return false;
        }
    }
    return true;
}

1
जब से आपने अनुकूलन का उल्लेख किया है :), अगर val1अशक्त है तो आपको इस कोड से NullPointerException if (!val1.equals(val2)) {
मिलेगी

यह हम में से सबसे अच्छा भी होता है :)। आपके उत्तर में इसे ठीक करने के लिए +1।
JohnDoDo

बिंदु लिया :) आशा है कि यह बहुत अधिक वोट नहीं मिलता है, अन्यथा यह बहुत समर्थन होने वाला है।
विक्टर Ionescu

1
आपने विचार नहीं किया कि नहीं js2है nullया नहीं js1हैnull
जिओ

यह कोड नेस्टेड ऑब्जेक्ट्स / सीक्वेंस के लिए काम नहीं करता है।
FabienB

3

आप zjsonpatch लाइब्रेरी का उपयोग कर सकते हैं , जो RFC 6902 (JSON पैच) के अनुसार अलग-अलग जानकारी प्रस्तुत करता है। इसका उपयोग करना बहुत आसान है। कृपया इसके उपयोग के लिए इसके विवरण पृष्ठ पर जाएँ


2

मैं http://json.org/java/ पर लाइब्रेरी ले equalsजाऊंगा, और JSONObject और JSONArray की विधि को एक गहरी समानता परीक्षण करने के लिए संशोधित करूंगा। यह सुनिश्चित करने के लिए कि यह बच्चों के आदेश के विपरीत काम करता है, आपको बस इतना करना है कि आंतरिक मानचित्र को ए TreeMap, या कुछ के साथ बदल दें Collections.sort()


4
यह महान नहीं है - यह वास्तव में कोड के साथ आना चाहिए जो कि तुलना करने के लिए है।
Chii

लेकिन उस कोड को लिखने की कल्पना करें जहां JSON किसी भी संरचना में कुछ भी हो सकता है ... उस पर तुलना लिखें! यह सभी प्रकार के HTML पृष्ठों के लिए तुलना लिखना पसंद करता है।
JPM

2

इसे इस्तेमाल करे:

public static boolean jsonsEqual(Object obj1, Object obj2) throws JSONException

    {
        if (!obj1.getClass().equals(obj2.getClass()))
        {
            return false;
        }

        if (obj1 instanceof JSONObject)
        {
            JSONObject jsonObj1 = (JSONObject) obj1;

            JSONObject jsonObj2 = (JSONObject) obj2;

            String[] names = JSONObject.getNames(jsonObj1);
            String[] names2 = JSONObject.getNames(jsonObj1);
            if (names.length != names2.length)
            {
                return false;
            }

            for (String fieldName:names)
            {
                Object obj1FieldValue = jsonObj1.get(fieldName);

                Object obj2FieldValue = jsonObj2.get(fieldName);

                if (!jsonsEqual(obj1FieldValue, obj2FieldValue))
                {
                    return false;
                }
            }
        }
        else if (obj1 instanceof JSONArray)
        {
            JSONArray obj1Array = (JSONArray) obj1;
            JSONArray obj2Array = (JSONArray) obj2;

            if (obj1Array.length() != obj2Array.length())
            {
                return false;
            }

            for (int i = 0; i < obj1Array.length(); i++)
            {
                boolean matchFound = false;

                for (int j = 0; j < obj2Array.length(); j++)
                {
                    if (jsonsEqual(obj1Array.get(i), obj2Array.get(j)))
                    {
                        matchFound = true;
                        break;
                    }
                }

                if (!matchFound)
                {
                    return false;
                }
            }
        }
        else
        {
            if (!obj1.equals(obj2))
            {
                return false;
            }
        }

        return true;
    }

jsonArrays के भीतर यह सच है अगर कुछ तत्व मेल खाते हैं, जैसा कि सभी तत्वों के विपरीत है।
मत्तीसगढ़

@matiasg - करता है if (obj1Array.length() != obj2Array.length())सुनिश्चित नहीं सभी तत्वों मेल खाना?
kwah

3
@kwah: nope। इस उदाहरण पर विचार करें: obj1Array = [1,1,1], obj2Array = [1,2,3]। यह सच हो जाएगा। इसके अलावा, भले ही तत्व मेल खाते हों, वे एक ही क्रम में होने चाहिए। यह [1,2,3] और [2,3,1] के लिए भी सही होगा, जो कि गलत है
matiasg


2

कराटे वास्तव में आप के लिए क्या देख रहे हैं। यहाँ एक उदाहरण है:

* def myJson = { foo: 'world', hey: 'ho', zee: [5], cat: { name: 'Billie' } }
* match myJson = { cat: { name: 'Billie' }, hey: 'ho', foo: 'world', zee: [5] }

(अस्वीकरण: देव यहां)


2

Jsons की तुलना करने के लिए मैं JSONCompare का उपयोग करने की सलाह देता हूं: https://github.com/fslev/json-compare

// Compare by regex
String expected = "{\"a\":\".*me.*\"}";
String actual = "{\"a\":\"some text\"}";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no extra elements
String expected = "[1,\"test\",4,\"!.*\"]";
String actual = "[4,1,\"test\"]";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[\"text\",\"test\"]";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[2018]";
JSONCompare.assertNotEquals(expected, actual);  // True

0

जैक्सन के साथ ऐसा करने के इच्छुक लोगों के लिए, आप json-unit का उपयोग कर सकते हैं ।

JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);

गलतियाँ बेमेल के प्रकार पर उपयोगी प्रतिक्रिया देती हैं:

java.lang.AssertionError: JSON documents have different values:
Different value found in node "heading.content[0].tag[0]". Expected 10209, got 10206.

0

कुछ और काम करना सही नहीं लगा, इसलिए मैंने यह लिखा:

private boolean jsonEquals(JsonNode actualJson, JsonNode expectJson) {
    if(actualJson.getNodeType() != expectJson.getNodeType()) return false;

    switch(expectJson.getNodeType()) {
    case NUMBER:
        return actualJson.asDouble() == expectJson.asDouble();
    case STRING:
    case BOOLEAN:
        return actualJson.asText().equals(expectJson.asText());
    case OBJECT:
        if(actualJson.size() != expectJson.size()) return false;

        Iterator<String> fieldIterator = actualJson.fieldNames();
        while(fieldIterator.hasNext()) {
            String fieldName = fieldIterator.next();
            if(!jsonEquals(actualJson.get(fieldName), expectJson.get(fieldName))) {
                return false;
            }
        }
        break;
    case ARRAY:
        if(actualJson.size() != expectJson.size()) return false;
        List<JsonNode> remaining = new ArrayList<>();
        expectJson.forEach(remaining::add);
        // O(N^2)   
        for(int i=0; i < actualJson.size(); ++i) {
            boolean oneEquals = false;
            for(int j=0; j < remaining.size(); ++j) {
                if(jsonEquals(actualJson.get(i), remaining.get(j))) {
                    oneEquals = true;
                    remaining.remove(j);
                    break;
                }
            }
            if(!oneEquals) return false;
        }
        break;
    default:
        throw new IllegalStateException();
    }
    return true;
}

0

दो JsonObject, JsonArray, JsonPrimitive और JasonElements की तुलना करने के लिए निम्नलिखित कोड अधिक सहायक होगा।

private boolean compareJson(JsonElement json1, JsonElement json2) {
        boolean isEqual = true;
        // Check whether both jsonElement are not null
        if (json1 != null && json2 != null) {

            // Check whether both jsonElement are objects
            if (json1.isJsonObject() && json2.isJsonObject()) {
                Set<Entry<String, JsonElement>> ens1 = ((JsonObject) json1).entrySet();
                Set<Entry<String, JsonElement>> ens2 = ((JsonObject) json2).entrySet();
                JsonObject json2obj = (JsonObject) json2;
                if (ens1 != null && ens2 != null) {
                    // (ens2.size() == ens1.size())
                    // Iterate JSON Elements with Key values
                    for (Entry<String, JsonElement> en : ens1) {
                        isEqual = isEqual && compareJson(en.getValue(), json2obj.get(en.getKey()));
                    }
                } else {
                    return false;
                }
            }

            // Check whether both jsonElement are arrays
            else if (json1.isJsonArray() && json2.isJsonArray()) {
                JsonArray jarr1 = json1.getAsJsonArray();
                JsonArray jarr2 = json2.getAsJsonArray();
                if (jarr1.size() != jarr2.size()) {
                    return false;
                } else {
                    int i = 0;
                    // Iterate JSON Array to JSON Elements
                    for (JsonElement je : jarr1) {
                        isEqual = isEqual && compareJson(je, jarr2.get(i));
                        i++;
                    }
                }
            }

            // Check whether both jsonElement are null
            else if (json1.isJsonNull() && json2.isJsonNull()) {
                return true;
            }

            // Check whether both jsonElement are primitives
            else if (json1.isJsonPrimitive() && json2.isJsonPrimitive()) {
                if (json1.equals(json2)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else if (json1 == null && json2 == null) {
            return true;
        } else {
            return false;
        }
        return isEqual;
    }


0

जवाबों को देखते हुए, मैंने JSONAssert की कोशिश की लेकिन यह विफल रहा। इसलिए मैंने जैक्सन को zjsonpatch के साथ इस्तेमाल किया। मैंने एसओ उत्तर में विवरण यहां पोस्ट किया है


-5

मेरे लिए यह समाधान, काम बहुत अच्छा है:

try {           
                // Getting The Array "Courses" from json1 & json2   
                Courses1 =json1.getJSONArray(TAG_COURSES1);
                Courses2 = json2.getJSONArray(TAG_COURSES);

                //LOOP FOR JSON1
                for(int i = 0; i < Courses1.length(); i++){
                    //LOOP FOR JSON2
                    for(int ii = 0; ii < Courses2.length(); ii++){
                        JSONObject courses1 = Courses1.getJSONObject(i);
                        JSONObject courses2 = Courses2.getJSONObject(ii);

                        // Storing each json1 item in variable
                        int courseID1 = courses1.getInt(TAG_COURSEID1);
                        Log.e("COURSEID2:", Integer.toString(courseID1));
                        String Rating1 = courses1.getString(TAG_RATING1);
                        int Status1 = courses1.getInt(TAG_STATUS1);
                        Log.e("Status1:", Integer.toString(Status1));      //Put the actual value for Status1 in log.             

                        // Storing each json2 item in variable
                        int courseID2 = courses2.getInt(TAG_COURSEID);
                        Log.e("COURSEID2:", Integer.toString(courseID));   //Put the actual value for CourseID in log
                        String Title2 = courses2.getString(TAG_TITLE);                      
                        String instructor2 = courses2.getString(TAG_INSTRUCTOR);
                        String length2 = courses2.getString(TAG_LENGTH);
                        String rating2 = courses2.getString(TAG_RATING);
                        String subject2 = courses2.getString(TAG_SUBJECT);
                        String description2 = courses2.getString(TAG_DESCRIPTION);

                        //Status1 = 5 from json1; Incomplete, Status1 =-1 Complete 
                        if(Status1 == 5 && courseID2 == courseID1){                                  

                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();         
                        //Storing the elements if condition is true.
                        map.put(TAG_COURSEID, Integer.toString(courseID2)); //pend for compare
                        map.put(TAG_TITLE, Title2);
                        map.put(TAG_INSTRUCTOR, instructor2);
                        map.put(TAG_LENGTH, length2);
                        map.put(TAG_RATING, rating2);
                        map.put(TAG_SUBJECT, subject2); //show it
                        map.put(TAG_DESCRIPTION, description2);

                        //adding HashList to ArrayList
                        contactList.add(map);
                        }//if
                    }//for2 (json2)
                } //for1 (json1)                
            }//Try

आशा है कि यह दूसरों की मदद करेगा।


बेशक, बस इस मामले में अपने मूल्यों और शर्तों, और देखने के प्रकार डाल; एक सूची पर हैशमैप।
जूलिस

1
यह कैसे करना है के लिए यह अच्छा उदाहरण है :)
पेट्र dsjezdský
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.