기술과 산업/언어 및 프레임워크
Java JSON 처리 실전 시리즈 4화 – JSON을 Java 객체로 역직렬화하기: 날짜, Enum, Optional 대응 전략
B컷개발자
2025. 5. 17. 14:23
728x90
Jackson을 활용해 JSON을 Java 객체로 역직렬화할 때 발생할 수 있는 날짜, Enum, Optional 타입 처리 문제를 실제 예제와 함께 분석하고 해결 방법을 정리합니다.
1. 역직렬화(Deserialization)란?
역직렬화란 JSON 문자열을 Java 객체로 변환하는 과정을 말합니다. Jackson에서는 ObjectMapper.readValue() 메서드로 간단하게 구현할 수 있습니다.
String json = "{\"name\":\"홍길동\", \"age\":30}";
User user = objectMapper.readValue(json, User.class);
하지만 필드 타입이 LocalDateTime, Enum, Optional처럼 단순하지 않을 경우 오류가 발생하기 쉽습니다. 실무에서는 이 세 가지가 가장 많이 문제를 일으킵니다.
2. 날짜(LocalDate, LocalDateTime) 역직렬화
문제 상황
{
"name": "홍길동",
"joinedAt": "2025-05-09 14:30:00"
}
public class User {
private String name;
private LocalDateTime joinedAt;
}
위 코드를 실행하면 다음과 같은 오류가 발생할 수 있습니다:
com.fasterxml.jackson.databind.exc.InvalidFormatException:
Cannot deserialize value of type `java.time.LocalDateTime`
해결 방법
- 전역 설정 (application.yml):
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
이 방식은 java.util.Date 계열에는 적용되지만, java.time에는 적용되지 않습니다.
- @JsonFormat 사용 (추천)
public class User {
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime joinedAt;
}
3. Enum 타입 역직렬화
문제 상황
{
"name": "홍길동",
"role": "ADMIN"
}
public class User {
private String name;
private Role role;
public enum Role {
USER, ADMIN
}
}
이 경우 기본적으로는 문자열로 매핑이 되지만, 다음과 같은 상황에서는 오류가 발생할 수 있습니다:
- JSON에 소문자("admin")로 들어온 경우
- Enum에 없는 값이 들어오는 경우
해결 방법
- Enum 이름을 대소문자 구분 없이 매핑
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
- 예외 처리 추가
@JsonCreator
public static Role from(String value) {
try {
return Role.valueOf(value.toUpperCase());
} catch (Exception e) {
return Role.USER;
}
}
위 방식은 잘못된 값이 들어왔을 때 기본값으로 대체하는 전략입니다.
4. Optional 필드 역직렬화
{
"name": "홍길동",
"email": "hong@example.com"
}
public class User {
private String name;
private Optional<String> email;
}
문제
Jackson은 기본적으로 Optional<T>을 처리할 수 있지만, 다음과 같은 조건이 필요합니다:
- Jackson 2.6 이상 사용
- jackson-datatype-jdk8 의존성 추가 필요
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
Spring Boot에서는 자동으로 이 모듈을 등록하지 않으므로 별도 등록이 필요합니다.
5. Spring Boot에서 역직렬화 오류 무시 설정
실무에서 자주 마주하는 문제 중 하나는 정의되지 않은 JSON 필드가 들어오는 경우입니다.
{
"name": "홍길동",
"age": 30,
"unknownField": "unexpected"
}
public class User {
private String name;
private int age;
}
이럴 경우 기본 설정에서는 UnrecognizedPropertyException이 발생합니다.
해결 방법
spring:
jackson:
deserialization:
fail-on-unknown-properties: false
혹은 Java 설정:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
결론 및 요약
문제 유형해결 방법
| LocalDateTime 오류 | @JsonFormat 패턴 지정 |
| Enum 대소문자 이슈 | MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS 사용 |
| Optional 처리 | jackson-datatype-jdk8 모듈 등록 필요 |
| 알 수 없는 필드 오류 | FAIL_ON_UNKNOWN_PROPERTIES 비활성화 |
다음 회차 예고
5화에서는 JSON 필드명을 자동으로 Camel ↔ Snake Case로 변환하는 전략을 다룹니다. @JsonNaming, 글로벌 설정, yml 기반 설정을 통해 코드와 JSON의 명확한 분리를 어떻게 할 수 있는지 실전 예제와 함께 소개합니다.
728x90