[Spring Boot] 문자열로 들어오는 날짜를 LocalDateTime으로 받는 법
🕰️ 날짜 타입으로 직렬화/역직렬화
문자열로 들어오는 날짜를 어떻게 LocalDate나 LocalDateTime 등으로 받을 수 있을까?
다음과 같이 문자열로 들어오는 값을 LocalDateTime 타입 필드(startDate, endDate)가 받으면 에러가 난다.
1
2024-10-03T15:11:49.686+09:00 WARN 14632 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.yoonji.adminproject.common.dto.response.CommonResponse<com.yoonji.adminproject.admin.dto.response.AdminUserListResponse> com.yoonji.adminproject.admin.controller.AdminUserController.searchUsersWithCursor(com.yoonji.adminproject.admin.dto.request.AdminUserSearchCondition) with 2 errors: [Field error in object 'adminUserSearchCondition' on field 'endDate': rejected value [2024-10-01 00:00:00]; codes [typeMismatch.adminUserSearchCondition.endDate,typeMismatch.endDate,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [adminUserSearchCondition.endDate,endDate]; arguments []; default message [endDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'endDate'; Failed to convert from type [java.lang.String] to type [@io.swagger.v3.oas.annotations.media.Schema java.time.LocalDateTime] for value [2024-10-01 00:00:00]]] [Field error in object 'adminUserSearchCondition' on field 'startDate': rejected value [2024-09-01 00:00:00]; codes [typeMismatch.adminUserSearchCondition.startDate,typeMismatch.startDate,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [adminUserSearchCondition.startDate,startDate]; arguments []; default message [startDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'startDate'; Failed to convert from type [java.lang.String] to type [@io.swagger.v3.oas.annotations.media.Schema java.time.LocalDateTime] for value [2024-09-01 00:00:00]]] ]
그렇다면 startDate, endDate의 타입을 String으로 해서 LocalDateTime으로 변환해야 하는 것인가?
아니다. 처음부터 LocalDateTime으로 받을 수 있는 방법이 있다. 그걸 알아보도록 하자.
🔗 URL 파라미터 처리
Spring에서 URL 파라미터를 받는 방법은 크게 2가지가 있다.
@ModelAttribute를 사용해서 DTO 객체로 받기@RequestParam를 사용해서 필드별로 받기
@ModelAttribute
1
2
3
4
5
6
7
8
9
10
11
12
@GetMapping("/get")
public String get(LocalDateDto dto) {
return "mission complete";
}
@Getter
@RequiredArgsConstructor
public class LocalDateDto {
private final String name;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private final LocalDateTime dateTime;
}
별도의 어노테이션을 지정하지 않으면 기본적으로 스프링은
@ModelAttribute를 할당한다.
@RequestParam
1
2
3
4
5
6
@GetMapping("/requestParameter")
public String get(
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@RequestParam(name = "dateTime") LocalDateTime dateTime) {
return "mission complete";
}
위와 같이 URL 파라미터로 날짜를 받을 때는 @DateTimeFormat 어노테이션을 사용한다.
📩 Request Body 처리
1
2
3
4
5
6
7
8
9
10
11
12
@PostMapping("/post")
public String post(@RequestBody LocalDateJsonDto localDateJsonDto) {
return "post mission complete";
}
@Getter
@NoArgsConstructor
public class LocalDateJsonDto {
private String name;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime dateTime;
}
POST 요청의 Request Body에서 날짜를 처리할 때는 @JsonFormat 어노테이션을 사용한다. 이는 Jackson 라이브러리가 처리한다.
📤 Response Body 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
@GetMapping("/response")
public LocalDateJsonDto response() {
return new LocalDateJsonDto("user", LocalDateTime.now());
}
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class LocalDateJsonDto {
private String name;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime dateTime;
}
Response Body에서 날짜를 원하는 형식으로 반환하려면 @JsonFormat 어노테이션을 사용한다.
⚖️ @DateTimeFormat vs @JsonFormat
| 특성 | @DateTimeFormat | @JsonFormat |
|---|---|---|
| 제공 | Spring Framework | Jackson 라이브러리 |
| 용도 | URL 파라미터, 폼 데이터 등 비 JSON 데이터의 날짜 포맷 지정 | JSON 데이터의 직렬화/역직렬화 시 날짜 포맷 지정 |
| 사용 위치 | @ModelAttribute와 @RequestParam에서 사용 |
Request Body와 Response Body에서 사용 |
- GET 요청 (URL 파라미터):
@DateTimeFormat사용 - Reqeust Body:
@JsonFormat사용 - Response Body:
@JsonFormat사용
참고
Leave a comment