[TIL] 23.06.30 Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default

hyewon jeong·2023년 6월 29일
1

TIL

목록 보기
134/138

1 . 문제점

레디스 캐시를 적용하기 위해 준비를 완료 한후 포스트맨으로 실행 결과
에러가 발생했다.

Could not write JSON: 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: 
com.team.final8teamproject.contact.service.NoticeServiceImpl$Result[
"data"]->java.util.ArrayList[0]-
>com.team.final8teamproject.contact.dto.NoticeResponse["createdDate"
])

현재 시점의 코드
CacheConfiguration

@Configuration
public class CacheConfiguration {
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory, ResourceLoader resourceLoader) {
        RedisCacheConfiguration defaultConfig
                = RedisCacheConfiguration.defaultCacheConfig()
                .disableCachingNullValues()
                .serializeValuesWith(
                        RedisSerializationContext
                                .SerializationPair
                                .fromSerializer(new GenericJackson2JsonRedisSerializer())
                );


        Map<String, RedisCacheConfiguration> redisCacheConfigMap
                = new HashMap<>();


        redisCacheConfigMap.put(
            CacheNames.GETNOTICE,
            defaultConfig.entryTtl(Duration.ofHours(4))
       ):
       
        return RedisCacheManager.builder(connectionFactory)
                .withInitialCacheConfigurations(redisCacheConfigMap)
                .build();
    }

}

1-1. 에러의 원인?

 .fromSerializer(new GenericJackson2JsonRedisSerializer())

이 오류는 Java 8의 날짜/시간 타입인 java.time.LocalDateTime이 기본적으로 지원되지 않아 발생합니다. Jackson은 이러한 타입을 직렬화할 수 없으며, 해당 타입을 처리하기 위해 "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" 모듈을 추가해야 합니다.

2 . 시도한 점

implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3'

먼저, 에러 로그에 나온대로 "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" 모듈을 dependency에 추가했다.

@JsonSerialize와 @JsonDeserialize 어노테이션을 붙였다.

  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm")
  private final LocalDateTime createdDate;
  //private final LocalDateTime modifiedDate;

해결 되었다.

NoticeResponse class

package com.team.final8teamproject.contact.dto;


@Getter
@NoArgsConstructor(force = true,access = AccessLevel.PROTECTED)
public class NoticeResponse {

  private final Long id;
  private final Long managerId;
  private final String title;
  private final String content;

  private final String image;
  @JsonSerialize(using = LocalDateTimeSerializer.class)
  @JsonDeserialize(using = LocalDateTimeDeserializer.class)
  @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm")
  private final LocalDateTime createdDate;
  //private final LocalDateTime modifiedDate;



  public NoticeResponse(Notice notice) {
    this.id = notice.getId();
    this.managerId = notice.getManagerId();
    this.title = notice.getTitle();
    this.content = notice.getContent();
    this.createdDate = notice.getCreatedDate();
    this.image = notice.getImageUrl(); // 이미지 url
  //  this.modifiedDate = notice.getModifiedDate();
  }
}

3 . 알게 된점

  • GenericJackson2JsonRedisSerializer() 은
    Java 8의 날짜/시간 타입인 java.time.LocalDateTime이 기본적으로 지원되지 않아 발생합니다. Jackson은 이러한 타입을 직렬화할 수 없으며, 해당 타입을 처리하기 위해 "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" 모듈을 추가해야 한다는 것을 알게 되었다.

  • GenericJackson2JsonRedisSerializer는 JSON 형식으로 데이터를 직렬화하므로 가독성이 좋고 다른 플랫폼과의 상호 운용성이 뛰어나다. 또한, 직렬화된 데이터를 직접 읽을 수 있다.

  • JdkSerializationRedisSerializer는 Java 직렬화를 사용하여 데이터를 직렬화하므로 이진 형식으로 저장된다. 읽거나 수정하기가 어렵고 다른 플랫폼과의 상호 운용성이 제한될 수 있습니다. 또한, 클래스의 변경에 따른 호환성 문제가 발생할 수 있다.

일반적으로 JSON 직렬화를 사용하는 GenericJackson2JsonRedisSerializer가 더 유연하고 사용하기 편리하며, 대부분의 상황에서 권장된다. 그러나 특정한 요구사항이나 상황에 따라 JdkSerializationRedisSerializer를 선택할 수도 있다.

profile
개발자꿈나무

0개의 댓글