본문 바로가기

Programing/Framework

[Jackson vs Gson] 오버라이딩한 메서드의 JSON serialize 테스트

기존에 JSON으로 만들던 객체에 메서드가 추가된다면 어떨까?

단순하게 생각하면 public 한 getter가 추가 되면 프로퍼티로 추가가 될 것 같다.

 

실험을 해보자.

테스트 DTO

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Apple {
    private String color;
    private int radius;
}

1. Gson 및 Jackson 대조군

import com.fasterxml.jackson.databind.ObjectMapper
import com.google.gson.Gson
import spock.lang.Specification

class AppleTest extends Specification {
    def "Gson"() {
        given:
        def apple = new Apple()
        apple.color = "red"
        apple.radius = 3

        and:
        def gson = new Gson()

        when:
        def result = gson.toJson(apple)

        then:
        result == '''{"color":"red","radius":3}'''
    }

    def "Jackson"() {
        given:
        def apple = new Apple()
        apple.color = "red"
        apple.radius = 3

        and:
        def mapper = new ObjectMapper()

        when:
        def result = mapper.writeValueAsString(apple)

        then:
        result == '''{"color":"red","radius":3}'''
    }
}

테스트는 통과한다.

대조군은 Green

 

2. Gson 및 Jackson 실험군

Apple 클래스에 아래와 같이 메서드를 추가했다.

@Getter
@Setter
public class Apple {
    private String color;
    private int radius;

    public boolean isSweet() {  // 추가한 메서드
        return true;
    }
}

Gson은 추가한 메서드에 영향을 받지 않지만, Jackson은 기존 테스트가 실패했다.

Jackson은 sweet 라는 프로퍼티가 추가되었다.

만약 추가된 프로퍼티를 Serialize를 막으려면 어떻게 할까?

Jackson의 경우 @JsonIgnore 을 붙이면 된다.

@Getter
@Setter
public class Apple {
    private String color;
    private int radius;

    @JsonIgnore
    public boolean isSweet() {  // 추가한 메서드
        return true;
    }
}

Apple이 인터페이스를 구현하고 있는 경우 오버라이드하는 메서드에 @JsonIgnore 을 붙이지 않으면 어떻게 될까 궁금해졌다.

 

다시 실험군을 만든다.

 

Fruits 인터페이스 추가

public interface Fruits {
    boolean isSweet();
}

Apple은 구현 Fruits 인터페이스를 구현한다.

@Getter
@Setter
public class Apple implements Fruits {
    private String color;
    private int radius;

    @Override
    public boolean isSweet() {
        return true;
    }
}

여기까지는 동일하게 테스트가 실패한다.

Fruits 인터페이스의 isSweet 메서드에 @JsonIgnore를 붙이면 테스트는 성공한다.

public interface Fruits {
    @JsonIgnore
    boolean isSweet();
}

즉, 구현하는 클래스의 메서드(isSweet)에 @JsonIgnore를 붙이지 않아도 JSON Serialize를 하지 않는 것이다.