Kiểm tra hai đối tượng JSON để tìm sự bình đẳng bỏ qua thứ tự con trong Java


233

Tôi đang tìm kiếm một thư viện phân tích cú pháp JSON hỗ trợ so sánh hai đối tượng JSON bỏ qua thứ tự con, đặc biệt để kiểm tra đơn vị trả về JSON từ một dịch vụ web.

Có bất kỳ thư viện JSON chính nào hỗ trợ điều này không? Thư viện org.json chỉ đơn giản là so sánh tham chiếu.


1
Không thể tuần tự hóa cả hai đối tượng để đại diện chuỗi và so sánh? Tôi đoán tất cả các thư viện hỗ trợ toString()để chuyển đổi đối tượng thành JSONchuỗi.
Teja Kantamneni

47
Điều đó giả định rằng thứ tự nối tiếp đến và từ các chuỗi luôn giống nhau. Tôi không thoải mái khi đưa ra giả định đó.
Jeff

Bạn nói đúng Jeff, nó không an toàn chút nào. Thử nghiệm này cho thấy một kịch bản trong đó ánh xạ giống nhau nhưng toString () không trả lại cùng một đầu ra: gist.github.com/anonymous/5974797 . Điều này là do HashMap bên dưới có thể phát triển và nếu bạn loại bỏ các khóa, mảng bên trong HashMap không bị thu hẹp.
Guillaume Perrot

Câu trả lời:


84

Là một điểm kiến ​​trúc chung, tôi thường khuyên không nên để phụ thuộc vào một định dạng tuần tự hóa cụ thể chảy ra ngoài lớp lưu trữ / mạng của bạn; do đó, trước tiên tôi khuyên bạn nên xem xét kiểm tra sự bình đẳng giữa các đối tượng ứng dụng của riêng bạn thay vì các biểu hiện JSON của chúng.

Phải nói rằng, tôi hiện là một fan hâm mộ lớn của Jackson mà tôi đã đọc nhanh về triển khai ObjectNode.equals () của họ cho thấy việc so sánh thành viên mà bạn muốn:

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

Phương pháp này không đối xứng, vì nó chỉ kiểm tra mối quan hệ 'tập hợp con' của trẻ em chứ không phải bình đẳng. đối tượng 'khác' có thể có nhiều con hơn trong _children và phương thức này vẫn sẽ trả về đúng.
Yoni

23
@Yoni: Không đúng, vì có một so sánh kích thước. Họ phải có cùng số lượng trẻ em cũng như cùng một đứa trẻ. @Jolly Roger: Trong trường hợp này, tôi không tuần tự hóa đối tượng từ JSON trở lại POJO, nhưng khi gửi JSON một hệ thống, tôi không thể dựa vào nó gửi lại theo định dạng chính xác mà tôi đã gửi nó
Jeff

1
@Jeff Điều này có làm việc cho bạn không? Trong Junit, assertEquals thất bại đối với tôi. Dự án đang sử dụng một phiên bản cũ (1.5), fyi.
ronnyfm 6/07/2015

1
Tôi nghĩ rằng bạn đang thiếu một số thử nghiệm cấp cao nếu bạn không khẳng định JSON. Bạn có thể có một bài kiểm tra mỏng đưa ra yêu cầu http và trả lời với một số JSON dự kiến ​​- đó là hành vi chức năng chính của dịch vụ web.
mogronalol

Chỉ cần một lưu ý nhỏ về hiệu suất: mã so sánh 'value' với 'otherValue' có thể được đơn giản hóa thành if (value.equals (other.get (key)) trả về false; vì 'value' được đảm bảo là không null và Phương thức equals () của JsonNode phải chấp nhận đối số null.
Tillmann

154

Hãy dùng thử JSONAssert của chọc trời .

Chế độ không nghiêm ngặt của nó có hai ưu điểm chính khiến nó ít giòn hơn:

  • Khả năng mở rộng đối tượng (ví dụ: Với giá trị dự kiến ​​là {id: 1} , điều này vẫn sẽ vượt qua: {id: 1, moredata: 'x'} .)
  • Sắp xếp mảng lỏng lẻo (ví dụ: ['dog', 'cat'] == ['cat', 'dog'])

Trong chế độ nghiêm ngặt, nó hoạt động giống như lớp kiểm tra của json-lib.

Một bài kiểm tra trông giống như thế này:

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

Các thông số trong JSONAssert.assertEquals () gọi được expectedJSONString , actualDataString , và isStrict .

Các thông báo kết quả khá rõ ràng, điều này rất quan trọng khi so sánh các đối tượng JSON thực sự lớn.


18
Tôi đã sử dụng giải pháp này, nhưng tôi vừa thấy rằng bạn cũng có thể cung cấp JSONCompareMode do bạn chọn. Một trong số đó là NON_EXTENSIBLE. Vì vậy, bạn sẽ có một cái gì đó như thế này: JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);Chế độ NON_EXTENSIBLE có nghĩa là bất kỳ trường mới hoặc thiếu nào đều gây ra lỗi, nhưng thứ tự thì không. Sử dụng sai sẽ kích hoạt chế độ khoan hồng sẽ không báo cáo bất kỳ phần tử con thừa hoặc thiếu nào.
Đền Dan

1
Chế độ so sánh NON_EXTENSIBLE chính xác là những gì tôi đang tìm kiếm. Cảm ơn vì điều này, Dan.
NghĩCrhyme

Trước khi tôi hết hứng thú: điều này có hỗ trợ các đối tượng và mảng JSON lồng nhau không? :)
Christian

2
Mọi người có thể muốn đưa vấn đề JSONassert này vào tài khoản trước khi sử dụng thư viện: nó chỉ ra rằng hiện tại có các vấn đề cấp phép tiềm năng với sự phụ thuộc của thư viện.
Chriki

3
Đã khắc phục sự cố # 44 của JSONAssert với thay thế thư viện phòng sạch trong PR 67, được phát hành ngày hôm nay với tên JSONAssert 1.4.0.
Carter Trang

49

Sử dụng 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);

Chỉnh sửa: Vì GSON v2.8.6 , phương thức cá thể JsonParser.parsekhông được dùng nữa. Bạn phải sử dụng phương thức tĩnh JsonParser.parseString:

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

Hoạt động trong GSON 2.8.2 cho tôi.
Tom Saleeba

1
nó không hoạt động nếu các phần tử jsonArray không theo thứ tự. phiên bản 2.8.2
Naveen Kumar RB

1
Không hoạt động với tôi nếu thứ tự của đối tượng / thành phần khác nhau
Jknair

Nó hoạt động với tôi vì tôi chỉ muốn nó cho một bài kiểm tra đơn vị trong đó hai thuộc tính của jsons có cùng thứ tự
GabrielBB

@GabrielBB Bạn nên chỉnh sửa câu hỏi và cho biết phiên bản API nào không được dùng nữa và trong phiên bản nào, kiểu mã mới bắt đầu hoạt động.
rõ ràng

30

Tôi sẽ làm như sau

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

Nếu bạn đang sử dụng Jackson thì đây là câu trả lời tốt nhất IMHO.
Christoph Dietze

18
Nhưng đây là một so sánh nghiêm ngặt tôi nghĩ. Nó sẽ trả về false cho hai json bằng nhau có thứ tự các phần tử khác nhau.
deadpool

@deadpool nguyên tắc là âm thanh, bạn chỉ cần thay đổi so sánh để được tham gia nhiều hơn (ví dụ: kiểm tra các trường chính chứ không phải là một cây bằng đơn giản).
jwenting

Đây là câu trả lời tốt nhất bao giờ hết. Nó không chỉ trả lời câu hỏi của tôi bây giờ, vì nó cũng trả lời hầu hết mọi so sánh đối tượng chúng ta cần làm. cảm ơn, joshu
Luiz Feijão Veronesi

2
@deadpool, nó có thể là một so sánh nghiêm ngặt, nhưng bây giờ nó không nghiêm ngặt.
Andrei Damian-Fekete

18

Bạn có thể thử sử dụng lớp JSONAssert của json-lib :

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

Cung cấp:

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

Hoặc thậm chí đơn giản hơn: JSONAssert.assertJsonEquals ("{foo: 'bar', baz: 'qux'}", {foo: 'bar', baz: 'xyzzy'} ");
Rob Juurlink

2
Khi giải pháp này hoạt động theo thứ tự các mục dữ liệu trong JSON, nó sẽ thất bại nếu thứ tự các phần tử trong mảng không khớp. Nếu mã của bạn sử dụng Tập hợp được chuyển đổi thành JSON chẳng hạn. So sánh JSON sau đây sẽ thất bại: JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }"); Với thông báo:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Dan Temple

Có, đây là một hạn chế của Json :(. Json.org cho thấy rằng không có mã thông báo bộ sưu tập không có thứ tự. {} Chỉ có thể bao quanh các cặp giá trị khóa. Điều này rất khó chịu
Merk

15

Sử dụng thư viện này: https://github.com/lukas-krecan/JsonUnit

Bưởi:

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

IGNORING_ARRAY_ORDER - bỏ qua thứ tự trong mảng

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

bạn có thể thêm bình luận về cách chúng tôi có thể sử dụng nó không? Tôi thêm nó vào pom của tôi nhưng chúng tôi cần tài liệu để hiểu cách sử dụng nó
Ran Adler

chắc chắn cách sử dụng rất đơn giản: Thêm cái này vào pom của bạn. <phụ thuộc> <groupId> net.javacrumbs.json-unit </ groupId> <artifactId> json-unit </ artifactId> <version> 1.5.0 </ version> <scope> test </ scope> </ Depencies>
chethu

10 lần tôi đã xem hướng dẫn tại đường dẫn và tôi đã tìm thấy nó :)
Ran Adler

12

Nếu bạn đã sử dụng JUnit, phiên bản mới nhất hiện sử dụng Hamcrest. Đó là một khung kết hợp chung (đặc biệt hữu ích cho thử nghiệm đơn vị) có thể được mở rộng để xây dựng các đối sánh mới.

Có một thư viện mã nguồn mở nhỏ được gọi hamcrest-jsonvới các đối sánh nhận biết JSON. Nó là tài liệu tốt, thử nghiệm và hỗ trợ. Dưới đây là một số liên kết hữu ích:

Mã ví dụ sử dụng các đối tượng từ thư viện JSON org.json.simple:

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

Tùy chọn, bạn có thể (1) cho phép mảng "bất kỳ thứ tự" và (2) bỏ qua các trường bổ sung.

Vì có rất nhiều thư viện JSON cho Java ( Jackson, GSON, json-lib, vv), nó rất hữu ích mà hamcrest-jsonhỗ trợ JSON văn bản (như java.lang.String), cũng như nguyên bản hỗ trợ các đối tượng từ thư viện JSON Douglas Crockfordorg.json .

Cuối cùng, nếu bạn không sử dụng JUnit, bạn có thể sử dụng Hamcrest trực tiếp để xác nhận. ( Tôi đã viết về nó ở đây. )


Lợi thế của việc sử dụng trình so khớp hamcrast thay vì sử dụng trực tiếp JSONAssert là gì?
Julian

2
@Johannes: Chỉ kiểu.
kevinarpe

Các nguồn hamcrest-json hiện có ngày cam kết cuối cùng của năm 2012. Nó có thể không còn được hỗ trợ tốt nữa.
Thorbjørn Ravn Andersen

11

Bạn có thể thử JsonUnit . Nó có thể so sánh hai đối tượng JSON và báo cáo sự khác biệt. Nó được xây dựng trên đỉnh Jackson.

Ví dụ

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

Kết quả trong

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

6

Một điều tôi đã làm và nó hoạt động kỳ diệu là đọc cả hai đối tượng vào HashMap và sau đó so sánh với một assertEquals () thông thường. Nó sẽ gọi phương thức equals () của hashmap, sẽ so sánh đệ quy tất cả các đối tượng bên trong (chúng sẽ là các hashtag khác hoặc một số đối tượng giá trị đơn lẻ như một chuỗi hoặc số nguyên). Điều này đã được thực hiện bằng cách sử dụng trình phân tích cú pháp Jackson JSON của Codehaus.

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

Một cách tiếp cận tương tự có thể được sử dụng nếu đối tượng JSON là một mảng thay thế.


6

Tôi đang sử dụng cái này và hoạt động tốt với tôi (với 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

Đối với org.json, tôi đã đưa ra giải pháp của riêng mình, một phương thức so sánh với các trường hợp JSONObject. Tôi đã không làm việc với các đối tượng JSON phức tạp trong dự án đó, vì vậy tôi không biết liệu điều này có hoạt động trong tất cả các kịch bản hay không. Ngoài ra, do tôi sử dụng điều này trong các bài kiểm tra đơn vị, tôi đã không nỗ lực tối ưu hóa. Đây là:

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
Vì bạn đã đề cập đến tối ưu hóa :), nếu val1là null, bạn sẽ nhận được if (!val1.equals(val2)) {
NullPulumException

Nó cũng xảy ra với những người tốt nhất của chúng ta :). +1 để sửa nó trong câu trả lời của bạn.
JohnDoDo

điểm thực hiện :) Hy vọng rằng nó không nhận được quá nhiều phiếu bầu, nếu không nó sẽ được hỗ trợ rất nhiều.
Victor Ionescu

1
Bạn đã không cân nhắc xem js2nullhay không khi js1khôngnull
Xiao

Mã này không hoạt động cho các đối tượng / chuỗi lồng nhau.
FabienB

3

Bạn có thể sử dụng thư viện zjsonpatch , trình bày thông tin khác theo RFC 6902 (Bản vá JSON). Nó rất dễ sử dụng. Vui lòng truy cập trang mô tả của nó để sử dụng


2

Tôi sẽ lấy thư viện tại http://json.org/java/ và sửa đổi equalsphương thức JSONObject và JSONArray để thực hiện một bài kiểm tra công bằng sâu sắc. Để chắc chắn rằng nó hoạt động không theo thứ tự của trẻ em, tất cả những gì bạn cần làm là thay thế bản đồ bên trong bằng một TreeMaphoặc sử dụng một cái gì đó như Collections.sort().


4
nó không tuyệt lắm - nó thực sự cần phải có mã để làm so sánh json.
Chii

Nhưng hãy tưởng tượng viết mã đó trong đó JSON có thể là bất cứ thứ gì trong bất kỳ cấu trúc nào ... hãy viết so sánh về điều đó! Nó giống như viết một so sánh cho tất cả các loại trang HTML.
JPM

2

Thử cái này:

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

trong jsonArrays điều này trả về true nếu một số phần tử trùng nhau, trái ngược với tất cả các phần tử trùng nhau.
matiasg

@matiasg - if (obj1Array.length() != obj2Array.length())không đảm bảo tất cả các yếu tố trùng khớp?
kwah

3
@kwah: không. Xem xét ví dụ này: obj1Array = [1,1,1], obj2Array = [1,2,3]. Điều này sẽ trở lại đúng sự thật. Ngoài ra, ngay cả khi các yếu tố trùng khớp, chúng nên theo cùng một thứ tự. Điều này cũng sẽ trả lại đúng cho [1,2,3] và [2,3,1], điều này là sai
matiasg


2

Karate chính xác là những gì bạn đang tìm kiếm. Đây là một ví dụ:

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

(từ chối trách nhiệm: dev ở đây)


2

Để so sánh jsons tôi khuyên bạn nên sử dụng 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

Đối với những người như tôi muốn làm điều này với Jackson, bạn có thể sử dụng json-unit .

JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);

Các lỗi cung cấp phản hồi hữu ích về loại không khớp:

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

0

Không có gì khác có vẻ hoạt động hoàn toàn đúng, vì vậy tôi đã viết điều này:

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

Mã sau sẽ hữu ích hơn để so sánh hai JsonObject, JsonArray, JsonPrimitive và 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

Nhìn vào các câu trả lời, tôi đã thử JSONAssert nhưng không thành công. Vì vậy, tôi đã sử dụng Jackson với zjsonpatch. Tôi đã đăng chi tiết trong câu trả lời SO ở đây .


-5

Giải pháp này cho tôi, công việc rất tốt:

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

Hy vọng điều này sẽ giúp người khác.


tất nhiên, chỉ cần đặt các giá trị và điều kiện của bạn, và loại quan điểm, trong trường hợp này; Hashmap trên một listview.
JLouis

1
Đây là ví dụ hay cho cách không làm điều đó :)
Petr Újezdský
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.