-
Java JSON 처리 실전 시리즈 4화 – JSON을 Java 객체로 역직렬화하기: 날짜, Enum, Optional 대응 전략기술과 산업/언어 및 프레임워크 2025. 5. 17. 14:23728x90
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'기술과 산업 > 언어 및 프레임워크' 카테고리의 다른 글
Java JSON 처리 실전 시리즈 6화 – Spring MVC에서 JSON 요청과 응답 처리 흐름: Jackson과 HttpMessageConverter 작동 원리 (0) 2025.05.19 Java JSON 처리 실전 시리즈 5화 – JSON 필드명 자동 변환: CamelCase ↔ Snake_Case 대응 전략 (0) 2025.05.19 JHipster 시리즈 6화 - JHipster 프로젝트 구조와 코드 흐름 분석하기 (3) 2025.05.15 Python 마스터 시리즈 10화 – 파일 입출력(IO)과 경로 처리의 실전 패턴 (1) 2025.05.15 NestJS 마스터 시리즈 14화. CRUD 실습 – 사용자(User) API를 완성해보자 (0) 2025.05.15