영호

[JAVA] Jackson사용 시 primitive boolean주의점 본문

Language/JAVA

[JAVA] Jackson사용 시 primitive boolean주의점

0h0 2023. 7. 23. 13:46

들어가면서,

이번 프로젝트 중 만든 DTO에 isRegistered라는 boolean타입 필드가 존재했다. 나는 해당 필드에 null이 들어갈 일이 없다고 생각해 primitive type인 boolean을 사용하면서 발생한 문제와 해결 방법에 대해 쓸 예정이다.

문제점

jackson라이브러리에서 primitive type인 boolean을 쓰고 필드명에 isXXX를 사용하면 is가 자동으로 삭제된다. 그래서 만약 isSuccess라는 필드가 boolean으로 선언되어 있다면 실제 반환되는 json에는 success가 들어가게된다.

해결방법

현재 내가 알고 있는 해결방법은 3가지가 있다.

@JsonProperty(value = "isXXX")

@JsonProperty를 사용하면 반환되는 json의 key이름을 내가 지정할 수 있다. 그러나 이 방법은 isXXXXXX가 동시에 반환된다는 문제가 있다.

public class jacksonBooleanTest {

    @Test
    void test() throws JsonProcessingException {
        String s = new ObjectMapper().writeValueAsString(new TestDto(true));
        System.out.println(s);
    }
}
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TestDto {

    @JsonProperty(value = "isSuccess")
    private boolean isSuccess;
}
{"success":false,"isSuccess":false}

이처럼 success, isSuccess가 모두 반환되는 것을 볼 수 있다.

Wrapper클래스 사용하기

boolean을 primitive가 아닌 Wrapper클래스인 Boolean을 사용하면 된다.

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TestDto {

    private Boolean isSuccess;
}
{"isSuccess":true}

getter메서드 네이밍 변경

보통 boolean의 getter는 getXXX가 아닌 isXXX로 생성된다. 이때, 해당 getter의 네이밍을 getIsXXX로 설정하면 우리가 원하는 대로isXXX로 반환된다.

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TestDto {


    private boolean isSuccess;

    public boolean getIsSuccess() {
        return isSuccess;
    }
}

결론

primitive type인 boolean을 쓰고 싶으면 getter의 네이밍을 getIsXXX로 하고, 그게 아니라면 Wrapper클래스인 Boolean을 사용해서 API명세에 맞는 DTO를 만드는게 좋아보인다.

Comments