Spring Security를 사용해 로그인 처리를 할 때, 성공 시 응답 본문에 Json 형식의 데이터를 담아 보내려고 했다.
그런데 LocalDateTime 타입의 createdAt에 대해 다음과 같은 예외가 발생했다.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Java 8 date/time type `java.time.LocalDateTime` not supported by default:
add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
(through reference chain: org.zerock.todolist.domain.user.dto.UserResponse["createdAt"])
Controller에서 응답 본문에 dto를 담아 보내는 것은 정상적으로 동작한다.
ResponseEntity.status(HttpStatus.OK).body(todoService.getTodoById(todoId))
위 문제를 해결하기 위해 objectMapper에 다음과 같이 JavaTimeModule을 등록해 준다.
objectMapper.registerModule(JavaTimeModule()).writeValue(response.writer, userToResponse)
JavaTimeModule
- Java 8의 날짜 및 시간 API인 JSR-310 데이터 타입을 지원하는 에드온 모듈
- LocalDateTime, LocalDate 등 Java 8의 날짜 및 시간 객체를 Json으로 직렬화/역직렬화하는 데 사용
JavaTimeModule을 설정하면 예외 없이 정상적으로 응답을 보낼 수 있다.
하지만 다음과 같이 createdAt(LocalDateTime)이 배열로 전달되는 것을 볼 수 있다.
위 문제를 해결하기 위해서 다음과 같이 LocalDateTime객체를 Json으로 직렬화 하는 코드를 추가한다.
dto에 @JsonSerialize(using = LocalDateTimeSerializer.class) 어노테이션을 붙여서 해결하는 방법도 있었는데 이 방법은 제대로 작동하지 않았다.
val DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSS"
objectMapper.registerModule(
JavaTimeModule().addSerializer(
LocalDateTime::class.java, LocalDateTimeSerializer(
DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))
)
)
.writeValue(response.writer, userToResponse)
위 코드를 추가하고 다시 프로젝트를 실행해 테스트 해보면 다음과 같이 정상적으로 출력되는 것을 볼 수 있다.
참고자료
'TIL(Today I Learned)' 카테고리의 다른 글
TIL - Swagger에서 Bearer Token 설정 (0) | 2024.05.22 |
---|---|
TIL - JWT Token 생성 및 검증(Access Token, Refresh Token) (0) | 2024.05.21 |
TIL - Spring Security에서 JSON으로 로그인 처리 (0) | 2024.05.17 |
TIL - Offset-based Pagination & Cursor-based Pagination (0) | 2024.05.16 |
TIL - SQL WITH 재귀 쿼리 (0) | 2024.05.14 |