스프링은 날짜를 어떻게 역직렬화할까?
(@DateTimeFormat, @JsonFormat)
{
"startDateTime": "2023-07-13 14:00",
"endDateTime": "2023-07-14 15:59"
}
1)@DateTimeFormat을 사용
//Request Dto
public record ScheduleRequest(
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime startDateTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime endDateTime) {
}
→에러! 데이터바인딩시 에러
어떻게 해결하는가?
2)@JsonFormat으로 해결
public record ScheduleRequest(
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
LocalDateTime startDateTime,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
LocalDateTime endDateTime) {
}
3)@DateTimeFormat vs @JsonFormat
@DateTimeFormat
package org.springframework.format.annotation;
...
public @interface DateTimeFormat {
...
}
→@DateTimeFormat은 Spring의 어노테이션
@JsonFormat
package com.fasterxml.jackson.annotation;
...
public @interface JsonFormat {
...
}
→ @JsonFormat은 @RequestBody, @ResponseBody를 사용한 직렬화/역직렬화를 담당하는 Jackson 라이브러리의 어노테이션이다.
-Jackson 라이브러리에서는 내부적으로 pattern으로 지정한 형식을 LocalDateTime으로 변환해준다.
따라서, Jackson 라이브러리의 @JsonFormat은 날짜 형식이라면 자유롭게 사용이 가능하다.
하지만, @RequestBody, @ResponseBody를 사용한 역직렬화/직렬화 시,
@DateTimeFormat을 사용하려면 Jackson 라이브러리에 있는 어노테이션이 아니기 때문에 LocalDateTime의 기본 형식인 'yyyy-MM-dd'T'HH:mm:ss'으로 요청이 들어와야 바인딩된다.
4) @RequestParam, @ModelAttribute에서는 무엇을 사용해야 할까?
@RequestBody, @ResponseBody 등 Jackson 라이브러리를 사용하여 역직렬화/직렬화를 하는 상황이 아닌 Jackson 라이브러리가 관여하지 않는 @RequestParam, @ModelAttribute에서는 무엇을 사용해야 할까?
Jackson 라이브러리가 사용되지 않기 때문에 @JsonFormat은 무시된다.
→ @DateTimeFormat을 사용하여 날짜 형식을 자유롭게 바인딩 할 수 있다.
5) 결론적으로 @RequestBody, @ResponseBody를 사용한 역직렬화/직렬화 시,
날짜 형식을 자유롭게 사용하기 위해서는, @DateTimeFormat이 아닌, @JsonFormat을 사용해야한다!
* 기본 전제 : LocalDateTime의 기본 형식인 'yyyy-MM-dd'T'HH:mm:ss'이 아닐 때
1. @RequestBody, @ResponseBody : @JsonFormat 사용
2. @RequestParam, @ModelAttribute : @DateTimeFormat 사용