Spring boot에서 enum을 유연하게 직렬화 및 역직렬화를 하려면 어떻게 해야할까?
enum에는 FOURTH_GRADE, FIFTH_GRADE, SIXTH_GRADE로 정의했지만, 이 상수로 프론트엔드와 데이터를 주고 받는다면 프론트엔드에서 4학년, 5학년, 6학년으로 재변환해야한다는 문제가 있었다.
이를 해결하기 위해 직렬화시 enum값을 4학년, 5학년, 6학년으로 변환하고, 역직렬화시에도 마찬가지로 이 값을 받아 OURTH_GRADE, FIFTH_GRADE, SIXTH_GRADE 상수로 변환되도록 구현하고 싶었다.
직렬화: 객체들의 데이터를 연속적인 데이터로 변형하여 전송가능한 형태로 만드는 것(ex. 객체 → JSON)
역직렬화: 직렬화된 데이터를 다시 객체 형태로 만드는 것(ex. JSON → 객체)
이를 위해 Jackson 라이브러리의 @JsonValue와 @JsonCreator를 사용하였다.
@JsonValue를 사용한 직렬화
@JsonValue는 전체 인스턴스를 직렬화할 때 사용하는 단일 메서드로, enum을 JSON으로 직렬화할 때 원하는 값을 반환하도록 지정할 수 있다.
만약, 이 어노테이션을 사용하지 않는다면 enum명으로 직렬화하게 된다.
@Slf4j
@RequiredArgsConstructor
public enum Age {
FOURTH_GRADE("4학년"),
FIFTH_GRADE("5학년"),
SIXTH_GRADE("6학년");
private final String name;
@JsonValue
public String getName() {
return name;
}
}
@JsonCreator를 사용한 역직렬화
@JsonCreator를 사용하면 JSON 문자열을 enum으로 역직렬화할 때 커스텀 로직을 정의할 수 있다.
@Slf4j
@RequiredArgsConstructor
public enum Age {
FOURTH_GRADE("4학년"),
FIFTH_GRADE("5학년"),
SIXTH_GRADE("6학년");
private final String name;
@JsonValue
public String getName() {
return name;
}
@JsonCreator
public static Age fromName(String name) {
for (Age age : Age.values()) { // Age.values(): Age enum에 정의된 모든 enum 상수를 반환 => [ FOURTH_GRADE, FIFTH_GRADE, SIXTH_GRADE ]
if (age.getName().equals(name)) {
return age;
}
}
log.info("존재하지 않는 enum type(Age): {}", name);
throw new IllegalArgumentException(name + "은 존재하지 않는 enum type입니다.(Age)");
}
}
이렇게 Jackson 라이브러리의 어노테이션을 사용하여, 직렬화시 enum 상수를 한글로 변환하고, 역직렬화시 한글을 enum 상수로 변환하는 기능을 구현할 수 있었다.
만약 enum의 요소가 많아지거나 해당 메서드를 호출해야하는 상황이 많아진다면?
다음과 같이 enum 상수를 Map에 미리 저장해둔다면, for문을 통해 매번 비교하지 않아도 되기 때문에 성능 최적화를 이룰 수 있다.
// static 블록에서 맵 초기화
static {
for (Age age : Age.values()) {
NAME_TO_ENUM_MAP.put(age.getName(), age);
}
}
참고 자료
https://pjh3749.tistory.com/281
https://yjkim-dev.tistory.com/102
'Spring boot' 카테고리의 다른 글
| JPA Entity Column의 기본값을 설정하는 방법 (0) | 2025.11.14 |
|---|