Object Mapper Local Date Time 직렬화 안되는 문제

알파로그·2023년 10월 13일
0

Error

목록 보기
35/37

✏️ 발단

  • 조회 api 의 통합 test 를 작성하던중 api 의 json 응답값을 java 객체로 변환하지 못하는 오류가 발생했다.

  • MockMvc 요청을 보내고 반환값 Json 을 java 객체로 변환하는 테스트 코드

@Test
void no2() throws Exception {
		ResultActions result = patchReq(mvc,
            mapping + "/v2/leader", jwt1, reqDto);

    StudyResDto resDto = toResDto(result, StudyResDto.class);
}
  • Json 을 Java 객체로 변환하는 메서드
public static <T> T toResDto(ResultActions result, Class<T> data) throws UnsupportedEncodingException, JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    MvcResult mvcResult = result.andReturn();

    return mapper.readValue(
            mvcResult.getResponse().getContentAsString(), data);
}
  • 에러
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 [Source: (String)"{"id":1,"createDate":[2023,10,7,11,52,39,940757000],"modifyDate":[2023,10,7,11,52,40,231822000],"name":"study1","about":"","leader":2,"capacity":10,"studyMember":2,"xp":0.0,"bronze":0,"silver":0,"gold":0,"diamond":0,"ruby":0,"platinum":0,"solvedCount":0,"ranking":null}"; line: 1, column: 22] (through reference chain: com.baeker.study.study.in.resDto.StudyResDto["createDate"])

✏️ 원인

  • api 의 Json 응답값을 DTO 로 변환할 때 DTO 의 필드값중 LocalDateTime 이 포함되어있었고 이 값을 변환하는데 실패가 원인이다.
    • java8 LocalDateTime 을 지원하지 않기 때문에 발생한 문제라고 한다.
@Data
@NoArgsConstructor
public class StudyResDto {

    private Long id;
    private LocalDateTime createDate; // 변환 실패
    private LocalDateTime modifyDate;

✏️ 문제 해결

📍 Java Time Module 을 추가해 문제 해결

  • 이 방법을 알기 전 Jackson datatype jsr310 라이브러리를 사용하거나,
    Custom Serializer 를 구현하는 등 방법을 했지만 지금 상황에 적합하지 않거나 정상적으로 작동되지 않았다.
    - Custom Serializer 는 공통로직인 변환 로직을 재사용성을 위해 별도로 분리했는데 static 을 선언하면 사용할 수 없어서 적용하지 않았다.
  • 해결 방법을 알아보던중 Object Mapper 로직렬화 하기전에 Java Time Module 을 등록하면 문제를 해결할 수 있다는 것을 알아냈다.
    • 단 하나의 메서드 호출을 추가로 매우 간단하게 문제를 해결할 수 있었다.
public static <T> T toResDto(ResultActions result, Class<T> data) throws UnsupportedEncodingException, JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    MvcResult mvcResult = result.andReturn();

    return mapper
				.registerModule(new JavaTimeModule()) // 모듈 추가
				.readValue(mvcResult.getResponse().getContentAsString(), data);
}
profile
잘못된 내용 PR 환영

0개의 댓글