프로젝트를 하다가 DTO로 Enum타입을 바로 받을 수 있을지 궁금했다. 기존에는 아래 코드처럼 DTO에서 Enum을 사용하려면 String으로 데이터를 받은 뒤, 해당 String 값으로 Enum 객체를 생성해줘야 했다. 이 방식은 2가지 불편한 점이 있었는데,
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class SignUp {
@NotNull(message = "성별을 선택해야 합니다.")
private String gender;
}
@AllArgsConstructor
public enum Gender implements EnumType {
MALE("남자"),
FEMALE("여자");
private final String description;
}
- 유효성 검증을 별도로 진행해줘야 한다. 만약 Enum 값으로 유효하지 않은 String 값이 전달될 수도 있다. 이를 방지하기 위해서 별도로 유효성 검증을 해줘야하고, 코드 복잡도를 증가시키게 된다.
- Enum 값을 생성하는 과정 역시 코드 복잡도를 증가시키게 된다. 전달 받은 String 값과 맞는 Enum 타입을 가져오기 위해서 switch문이나 if문을 작성해줘야 했다.
이러한 과정을 자동화하면 편하지 않을까? 이번에는 Jackson 라이브러리를 통해 Deserialize하는 과정에서 Enum으로 값을 받아오는 방법을 알아보자
Json Body를 받아올 때 Json에서 Object하는 과정을 Deserialize(역직렬화)라고 한다. 이 Deserialize는 Jackson 라이브러리에서 실행하게 된다.
아래처럼 String으로 받던 gender 필드의 타입을 Gender Enum 타입으로 변경했다. 만약 이대로만 둔채로 SignUp DTO를 받는다면 에러가 나게 된다.
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public static class SignUp
@NotNull(message = "성별을 선택해야 합니다.")
private Gender gender;
}
이 때 @JsonCreator 애너테이션이 필요하다. SignUp DTO로 API 요청을 받으면 Gender에 들어가야할 String 값으로 받은 데이터는 @JsonCreator가 붙은 메서드의 파라미터로 들어온다.
아래 from 메서드를 살펴보면 들어온 String 값이 Gender의 value에 포함되는지 확인하고 만약 포함된다면 해당 Gender를 반환하고 없다면 잘못된 값이 전달된 것이기 때문에 예외를 발생시키도록 했다. 만약 예외 발생 없이 값이 올바르게 반횐됐따면 SignUp DTO의 Gender gender 값으로 들어가게 된다.
@AllArgsConstructor
public enum Gender implements EnumType {
MALE("남자"),
FEMALE("여자");
private final String description;
@JsonCreator
public static Gender from(String sub) {
for (Gender gender : Gender.values()) {
if (gender.getDescription().equals(sub)) {
return gender;
}
}
log.debug("EnumCollection.Gender.from() exception occur sub: {}", sub);
throw new BusinessLogicException(ExceptionCode.INVALID_GENDER);
}
}
어떻게 이렇게 작동하는걸까? 답을 알기 위해서는 @JsonCreator에 대해 알아봐야 한다.
@JsonCreator는 JSON 데이터에서 Enum 값을 역직렬화할 때 사용된다. 일반적으로 JSON 데이터에서 Enum 값을 역직렬화하기 위해서 해당 Enum의 문자열 값과 일치하는 문자열을 파싱해서 Enum 객체를 생성했다.
@JsonCreator를 사용하면 JSON 데이터를 역직렬화할 때 해당 Enum 객체를 직접 생성할 수 있다. 이를 통해 DTO에서 Enum을 받을 수 있게 된다. @JsonCreator는 메서드나 생성자에 붙여서 사용할 수 있다.
'Java' 카테고리의 다른 글
Mybatis - SAXParseException: The content of elements must consist of well-formed character data or markup 원인과 해결법 (0) | 2024.06.05 |
---|---|
Java - File로 파일 목록 이름 조회하기 (1) | 2024.01.25 |
Java - 커스텀 애너테이션으로 유효성 검사하기 (0) | 2023.04.22 |
Java - 제네릭(Generic)과 함께하는 리팩토링 (0) | 2023.04.17 |
Java - @NotNull, @NotEmptty, @Notblank 차이점 알고 쓰시나요? (0) | 2023.04.04 |