Java - Java 8 Local Date Time 직렬화/역직렬화 에러 원인과 해결 방법
배경
테스트 코드를 짜면서 HttpServletResponse 객체를 ObjectMapper를 통해 Dto로 객체로 역직렬화하는 과정에서 에러가 발생했다.
@Test
@DisplayName("회원 정보 수정")
void patchMemberTest() throws Exception {
...
String response = actions.andReturn().getResponse().getContentAsString();
Response responseDto = objectMapper.readValue(response, Response.class); // 여기서 에러 발생!
...
}
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 at...
원인
에러 메세지를 읽어보면 Java 8 LocalDateTime을 지원하지 않는다고 한다. 'jackson-datatype-jsr310'을 주입해서 추가하면 해결된다고 한다.
그래서 LocalDateTime 필드를 ObjectMapper로 역직렬화, 직렬화할 경우 에러가 발생했던 것이다.
해결
jackson-datatype-jsr310는 Java 8에서 추가된 java.time 패키지의 날짜 및 시간 API를 지원하는 Jackson 모듈이다. jackson-datatype-jsr310를 사용하면 Object Mapper로 Local Date Time을 직렬화할 수 있다.
하지만 jackson-datatype-jsr310는 Jackson 2.8.0 버전 이전에는 제공되지 않는다. Jackson 2.8.0 이전 버전에서는 JavaTimeModule을 사용해서 해결할 수 있다. 내가 진행중인 프로젝트는 Jackson 2.8.0 이전 버전이었기 때문에 JavaTimeModule을 사용했다.
ObjectMapper로 직렬화, 역직렬화하기 전에 JavaTimeModule을 등록하면 된다.
@Test
@DisplayName("회원 정보 수정")
void patchMemberTest() throws Exception {
...
String response = actions.andReturn().getResponse().getContentAsString();
Response responseDto = objectMapper.registerModule(new JavaTimeModule()) // JavaTimeModule 모듈 추가
.readValue(response, Response.class);
...
}
참조
serialize/deserialize java 8 java.time with Jackson JSON mapper
How do I use Jackson JSON mapper with Java 8 LocalDateTime? org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class java.time.LocalDateTime] from JSON
stackoverflow.com