JSON과 Enum 필드 상호 변환 : @JsonValue, @JsonCreator, @JsonFormat (+@JsonProperty)
이 프로젝트에서는 스프링의 Rest Controller에서 사용하는 DTO 클래스의 Enum 필드가 JSON으로 어떻게 변환되는지, 그리고 JSON이 어떻게 다시 Enum 필드로 변환되는지에 대해 알아보았습니다.
1. Default
public enum MyEnumV1 {
VALUE("value"),
UNDER_SCORE("underscore")
;
private final String value;
MyEnumV1(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
1.1. Response
Enum 필드는 Json으로 변환될 때, 일반적으로 해당 필드의 변수 명이 key가 되고, Enum의 열거형 상수 명이 value가 됩니다.
{
"name": "test 1",
"anEnum": "UNDER_SCORE"
}
1.2 Request
반대로 Json에서 Enum 필드로 변환될 때는, 열거형 상수 명 또는 순서를 이용하여 요청할 수 있습니다.
- 이름으로 요청하는 경우, 열거형 상수 명을 사용합니다.
- 순서로 요청하는 경우, 열거형 상수가 정의된 순서를 사용합니다. (순서는 0부터 시작)
// 열거형 상수 명으로 요청
{
"name": "test 1",
"anEnum": "UNDER_SCORE"
}
// 열거형 상수의 순서를 이용해서 요청
{
"name": "test 1",
"anEnum": 1
}
2. @JsonValue / @JsonCreator
@JsonValue 어노테이션을 메서드에 적용하면, 해당 메서드가 반환하는 값을 Json의 value로 사용합니다.
- @JsonValue가 단독으로 있다면, Response와 Request 모두 이 메서드의 반환값을 value로 사용합니다.
- @JsonCreator 어노테이션을 사용하는 메서드도 함께 있다면, Request에서는 @JsonCreator가 적용된 메서드를 이용해서 Json의 value를 Enum 필드로 변환합니다.
public enum MyEnumV2 {
VALUE("value"),
UNDER_SCORE("underscore")
;
private final String value;
MyEnumV2(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@JsonCreator
public static MyEnumV2 forValue(String value) {
for (MyEnumV2 myEnumV2 : MyEnumV2.values()) {
if (myEnumV2.getValue().equals(value)) {
System.out.println("@JsonCreator: " + myEnumV2.getValue());
return myEnumV2;
}
}
throw new IllegalArgumentException("Invalid value: " + value);
}
}
2.1. Response
{
"name": "test 2",
"anEnum": "underscore"
}
2.2. Request
@JsonCreator가 붙은 메서드에는 JSON의 value가 파라미터로 전달되고, 이 메서드는 value에 해당하는 Enum 상수를 반환합니다
{
"name": "test 2",
"anEnum": "underscore"
}
3. @JsonFormat
Enum 클래스에 @JsonFormat(shape = JsonFormat.Shape.OBJECT)
옵션을 적용하면, 해당 Enum 클래스의 모든 필드를 반환합니다.
이때, 필드에 대한 Getter가 없으면 에러 메시지도 없이 빈 객체가 반환하니 주의해야 합니다. (예: "enum": {} )
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
@Getter
public enum MyEnumV3 {
VALUE("value", 100),
UNDER_SCORE("underscore", 200)
;
private final String value;
private final int num;
MyEnumV3(String value, int num) {
this.value = value;
this.num = num;
}
}
3.1. Response
{
"name": "test 3",
"anEnum": {
"value": "underscore",
"num": 200
}
}
4. @JsonProperty
Enum에만 해당하는 내용은 아니지만, DTO 클래스의 필드에 @JsonProperty 어노테이션을 적용하면, Json의 Key 이름을 변경할 수 있습니다.
@AllArgsConstructor
@Getter
public class EnumDtoV3 {
private String name;
@JsonProperty("enum")
private MyEnumV3 anEnum;
}
4.1. Response
{
"name": "test 4",
"enum": {
"value": "underscore",
"num": 200
}
}
'Spring' 카테고리의 다른 글
[Spring] OAuth2 로그인 구현하기 2 - 로그인 과정 디버깅 (0) | 2023.08.22 |
---|---|
[Spring] OAuth2 로그인 구현하기 1 - 카카오 애플리케이션 등록 (0) | 2023.08.16 |
CORS 개념과 Spring 서버에서의 CORS 설정 및 테스트 (0) | 2023.07.31 |
Thymeleaf - Basic (0) | 2023.02.17 |
@Profile, @ActiveProfiles (0) | 2022.12.28 |