Spring Boot에서 LocalDateTime
을 API 응답으로 내려줄 때, 우리가 기대하는 "2025-05-02 03:47:19"
같은 문자열이 아니라 이상한 숫자 배열이나 timestamp 형태로 응답되는 경우를 많이 겪었을 것이다.
이 글에서는 왜 그런 현상이 생기는지, 그리고 어떻게 해결할 수 있는지 정리했다.
Spring Boot에서는 기본적으로 Jackson
라이브러리를 통해 객체를 JSON으로 직렬화한다.
하지만 LocalDateTime
은 Jackson 기본 설정에 의해 이렇게 [year, month, day, hour, minute, second, nano]
배열 형태나 숫자 형태의 timestamp
로 처리된다.
[2025, 5, 2, 3, 47, 19, 939277000]
혹은
20255234719939277000
이런 현상은 Spring Boot가 사용하는 JSON 직렬화 도구인 Jackson의 기본 설정 때문이다. Jackson은 Java 8의 LocalDateTime
을 자동으로 지원하지 않으며, JSR-310(java.time
)을 제대로 처리하기 위해서는 별도 모듈을 등록하거나 설정을 명시적으로 바꿔야 한다.
Spring Boot는 Jackson을 통해 객체를 JSON으로 직렬화한다. 그러나 Java 8의 LocalDateTime
은 Jackson 2.x 기준으로 기본 지원 대상이 아니며, 아래와 같은 문제가 발생한다:
LocalDateTime
, LocalDate
, ZonedDateTime
)을 배열 형태로 직렬화ObjectMapper
가 WRITE_DATES_AS_TIMESTAMPS
설정을 true로 유지할 경우 timestamp처럼 처리spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
serialization:
write-dates-as-timestamps: false
date-format
: 우리가 원하는 문자열 형식 지정write-dates-as-timestamps: false
: timestamp 형태 사용 금지이 설정을 통해 Jackson은 날짜/시간을 배열이나 timestamp가 아닌, 우리가 원하는 문자열 포맷으로 직렬화한다. 단, 이 방법은 java.util.Date
, java.sql.Timestamp
등 구형 날짜 클래스에는 적용되지만, LocalDateTime
에는 일부 제한이 있다.
엔티티나 DTO 클래스의 필드에 직접 적용하고 싶을 때 어노테이션을 붙이는 것이 확실하다.
@JsonFormat(pattern = "yyyy.MM.dd HH:mm:ss")
private LocalDateTime createdAt;
Jackson이 이 어노테이션을 통해 해당 필드만 원하는 포맷으로 직렬화한다. 포맷을 변경하거나 필드별로 다르게 적용하고 싶은 경우 유용하다.
이제 응답에서 아래처럼 문자열 포맷으로 잘 나오는 걸 확인할 수 있다.
"createdAt": "2025.05.02 03:47:19"
LocalDateTime
은 기본적으로 배열이나 timestamp처럼 내려온다.application.yml
) 또는 개별 설정(@JsonFormat
) 중 선택 가능