1. 개요

이 예제에서는 Java용 JSON 처리 라이브러리인 Jackson을 사용하여 두 개의 JSON 개체를 비교하는 방법을 살펴보겠습니다 .

2. 메이븐 의존성

먼저 jackson-databind Maven 의존성을 추가해 보겠습니다 .

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

3. Jackson을 사용하여 두 개의 JSON 개체 비교

ObjectMapper 클래스를 사용하여 객체를 JsonNode 로 읽습니다 .

ObjectMapper를 만들어 봅시다 .

ObjectMapper mapper = new ObjectMapper();

3.1. 두 개의 간단한 JSON 개체 비교

JsonNode.equals 메서드를 사용하여 시작하겠습니다 . equals () 메서드는 전체(심층) 비교를 수행합니다.

s1 변수 로 정의된 JSON 문자열이 있다고 가정합니다 .

{
    "employee":
    {
        "id": "1212",
        "fullName": "John Miles",
        "age": 34
    }
}

그리고 이를 다른 JSON인 s2 와 비교하려고 합니다 .

{   
    "employee":
    {
        "id": "1212",
        "age": 34,
        "fullName": "John Miles"
    }
}

입력 JSON을 JsonNode 로 읽고 비교해 보겠습니다.

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

입력 JSON 변수 s1s2 의 속성 순서가 동일하지 않더라도 equals() 메서드는 순서를 무시하고 동일한 것으로 취급한다는 점에 유의해야 합니다 .

3.2. 두 개의 JSON 개체를 중첩 요소와 비교

다음으로 중첩 요소가 있는 두 JSON 개체를 비교하는 방법을 살펴보겠습니다.

s1 변수 로 정의된 JSON부터 시작하겠습니다 .

{ 
    "employee":
    {
        "id": "1212",
        "fullName":"John Miles",
        "age": 34,
        "contact":
        {
            "email": "john@xyz.com",
            "phone": "9999999999"
        }
    }
}

보시다시피 JSON에는 중첩된 요소인 contact 이 포함되어 있습니다 .

s2 로 정의된 다른 JSON과 비교하려고 합니다 .

{
    "employee":
    {
        "id": "1212",
        "age": 34,
        "fullName": "John Miles",
        "contact":
        {
            "email": "john@xyz.com",
            "phone": "9999999999"
        }
    }
}

입력 JSON을 JsonNode 로 읽고 비교해 보겠습니다.

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

다시 말하지만 equals()는 두 개의 입력 JSON 개체를 중첩된 요소와 비교할 수도 있습니다.

3.3. List 요소를 포함하는 두 개의 JSON 개체 비교

마찬가지로 List 요소를 포함하는 두 개의 JSON 개체를 비교할 수도 있습니다.

s1 로 정의된 이 JSON을 살펴보겠습니다 .

{
    "employee":
    {
        "id": "1212",
        "fullName": "John Miles",
        "age": 34,
        "skills": ["Java", "C++", "Python"]
    }
}

다른 JSON인 s2 와 비교하고 있습니다 .

{
    "employee":
    {
        "id": "1212",
        "age": 34,
        "fullName": "John Miles",
        "skills": ["Java", "C++", "Python"] 
    } 
}

입력 JSON을 JsonNode 로 읽고 비교해 보겠습니다.

assertEquals(mapper.readTree(s1), mapper.readTree(s2));

두 개의 List 요소가 동일한 순서로 동일한 값을 갖는 경우에만 동일한 것으로 비교된다는 점을 아는 것이 중요합니다 .

4. 두 개의 JSON 개체를 사용자 지정 비교기와 비교

JsonNode.equals는 대부분의 경우 잘 작동합니다. Jackson은 또한 JsonNode.equals(comparator, JsonNode)를 제공하여 사용자 정의 Java Comparator 개체를 구성합니다.

사용자 정의 Comparator 를 사용하는 방법을 이해해 봅시다 .

4.1. 숫자 값을 비교하기 위한 사용자 지정 비교기

사용자 지정 Comparator를  사용하여 숫자 값이 있는 두 JSON 요소를 비교하는 방법을 살펴보겠습니다 .

이 JSON을 입력 s1 로 사용합니다 .

{
    "name": "John",
    "score": 5.0
}

s2 로 정의된 다른 JSON과 비교해 보겠습니다 .

{
    "name": "John",
    "score": 5
}

입력 s1s2 의 속성 점수 값이 동일하지 않다는 것을 관찰해야 합니다 .

입력 JSON을 JsonNode 로 읽고 비교해 보겠습니다.

JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);

assertNotEquals(actualObj1, actualObj2);

두 개체가 같지 않음에 유의하십시오. 표준 equals() 메서드는 값 5.0과 5를 다른 것으로 간주합니다.

그러나 사용자 정의 비교기를 사용하여 값 5와 5.0을 비교하고 동일하게 취급할 수 있습니다.

먼저 두 개의 NumericNode 개체를 비교하기 위해 Comparator를 생성해 보겠습니다 .

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 = ((NumericNode) o1).asDouble();
            Double d2 = ((NumericNode) o2).asDouble(); 
            if (d1.compareTo(d2) == 0) {
               return 0;
            }
        }
        return 1;
    }
}

다음으로 이 비교기를 사용하는 방법을 살펴보겠습니다 .

NumericNodeComparator cmp = new NumericNodeComparator();
assertTrue(actualObj1.equals(cmp, actualObj2));

4.2. 텍스트 값을 비교하기 위한 사용자 지정 비교기

두 JSON 값의 대/소문자를 구분하지 않는 비교를 위한 사용자 지정 Comparator 의 또 다른 예를 살펴보겠습니다 .

이 JSON을 입력 s1 로 사용합니다 .

{
    "name": "john", 
    "score": 5 
}

s2 로 정의된 다른 JSON과 비교해 보겠습니다 .

{ 
    "name": "JOHN", 
    "score": 5 
}

보시다시피 속성 이름은 입력 s1 에서 소문자 이고 s2 에서 대문자입니다 .

먼저 두 개의 TextNode 개체를 비교하기 위해 Comparator를 만들어 보겠습니다 .

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 = ((TextNode) o1).asText();
            String s2 = ((TextNode) o2).asText();
            if (s1.equalsIgnoreCase(s2)) {
                return 0;
            }
        }
        return 1;
    }
}

TextNodeComparator를 사용하여 s1s2를 비교하는 방법을 살펴보겠습니다 .

JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);

TextNodeComparator cmp = new TextNodeComparator();

assertNotEquals(actualObj1, actualObj2);
assertTrue(actualObj1.equals(cmp, actualObj2));

마지막으로, 입력 JSON 요소 값이 정확히 동일하지 않지만 여전히 동일한 것으로 취급하려는 경우 두 JSON 개체를 비교하는 동안 사용자 지정 비교기 개체를 사용하는 것을 볼 수 있습니다 .

5. 결론

이 빠른 기사에서는 Jackson을 사용하여 두 개의 JSON 객체를 비교하고 사용자 정의 비교기를 사용하는 방법을 살펴보았습니다

항상 그렇듯이 여기에서 논의된 모든 예제의 전체 소스 코드는 GitHub 에서 찾을 수 있습니다 .

res – Jackson (eBook) (cat=Jackson)