Jackson사용 시 primitive boolean주의점
개발을 하면서 DTO 클래스의 필드를 정의할 때, boolean 타입을 사용했다. 필드 이름을 isXXX 형태로 작성했는데, @RequestBody 를 사용하는 컨트롤러 단계에서 true 보내는데 계속 false로 서버에 전달되는 문제가 발생하였다.
그 이유는 다음과 같다
JSON 변환 시 Getter를 사용하기 때문에 Getter를 무조건 생성해야하는데, lombok 의 @Getter 를 사용하면 boolean 필드의 getter를 만들 때 getXXX 처럼 만드는게 아니라 isXXX 처럼 메서드명을 짓는다. 따라서 정상적인 getXXX 형태가 아니기 때문에 제대로 역직렬화가 되지 않는 것이다.
이를 해결하기 위한 방법으로는 다음 방법들이 존재한다.
방법 1 - Getter 직접 생성
lombok을 사용하지 않고 getter를 직접 개발자가 코드로 getIsXXX와 같이 생성해주면 boolean 타입을 사용해도 무관하다.
방법 2 - Boolean 타입으로 변경
JSON 변환 시Getter를 사용하기 때문에 Getter를 무조건 생성해야하는데, Boolean 타입을 사용하게 되면 Getter로 getIsXXX가 생성되기 때문에 이것을 사용하면 해결이 가능하다.
방법 3 - @JsonProperty (비추천)
@JsonProperty로 직접 전달 받을 필드명을 지정해주면 해결할 수 있다.
하지만, 이 방법은 추천하지 않는다. 왜냐하면, jackson이 값을 직렬화할 때 @JsonProperty가 있으면 필드 이름이 isXXX 일 때, isXXX가 있으니까 ‘isXXX’을 만들어주고 getter를 보니 isXXX이라는 getter가 있으니까 ‘XXX’을 만들어 주기 때문에 값이 2개 생기는 일이 발생하는 것이다.
방법 4 - boolean 변수명에서 is prefix를 제거
이 방법도 가능하지만, 나는 is~ 로 표현하는 것이 직관적이라 판단해서 is~ 를 그대로 사용하기로 했다.
방법 5. Enum 사용하기
@Getter
@ToString
public class MemberCreateRequest {
private MemberType memberType;
private String username;
public enum MemberType {
ADMIN, NON_ADMIN
}
}
boolean 값이 요구되는 비즈니스 로직의 경우 일반적으로 enum 으로 바꾸는 것이 그리 부자연스럽지는 않았다. 또, 이렇게 변경하면 단순 true/false 로만 표현할 수 없는 상황에 대해 더 유연하게 대응할 수도 있다. 물론, boolean 의 역직렬화 오류를 피하자고 이렇게 까지 하는 것은 너무 하는 것 아닌가? 라고 생각할 수도 있겠다. 그런데 아주 약간의 공수만 들이면 더 안전한 설계가 가능하다.
'개발기록(feat.삽질)' 카테고리의 다른 글
| JPA Bulk Insert (1) | 2024.12.13 |
|---|---|
| [Querydsl] java.time.LocalDateTime is not compatible with java.lang.String 에러 (0) | 2024.10.23 |
| JPA Union 및 Enum 사용 (feat.네이티브 쿼리, SpEL) (0) | 2024.07.12 |
| git add, commit, push (0) | 2024.07.09 |
| @JsonCreater : Enum Type Request Dto Mapping (0) | 2024.07.09 |