본문 바로가기
Backend/Java-Spring

[Redis] LocalDateTime 직렬화/역직렬화 오류 발생

by 벨롭 2024. 11. 24.

 

| 오류 내용 (What)

 

 

  • 이번 달 출석 기록 히스토리(List<LocalDateTime>)를 Redis에 저장하는 과정에서 직렬화/역직렬화 오류 발생.

 

 

 

| 오류 원인 (Why)

 

  • LocalDateTime과 같은 Java의 날짜/시간 타입은 Jackson에서 별도의 모듈(JavaTimeModule)을 추가적으로 등록하거나 커스텀 직렬화/역직렬화를 거쳐야만 직렬화/역직렬화가 가능하다.

 

  • LocalDateTime을 String으로 변환하는 것으로도 직렬화/역직렬화가 가능했겠지만, 확장성과 유지보수성을 고려하여 Redis Config를 수정하였다.

 

 

| 코드 상세 설명 (How)

@Configuration
public class RedisConfig {

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(
        RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        PolymorphicTypeValidator typeValidator = BasicPolymorphicTypeValidator
            .builder()
            .allowIfSubType(Object.class)
            .build();

        ObjectMapper objectMapper = new ObjectMapper()
            .findAndRegisterModules()
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
            .activateDefaultTyping(typeValidator, DefaultTyping.NON_FINAL)
            .registerModule(new JavaTimeModule());

        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));

        return template;
    }
}

 

 

RedisConfig에 JavaTimeModule을 등록하고 모든 객체의 클래스 타입 정보를 포함시키도록 설정하였다.

 

 

 

1. PolymorphicTypeValidator

 

1) 모든 객체를 직렬화/역직렬화 할 수 있도록 타입 검증 로직 설정

.allowIfSubType(Object.class)

  

 

 

2. ObjectMapper

 

1) 날짜를 타임스탬프 대신 ISO-8601 형식으로 직렬화

.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)

   

 

2) 직렬화된 JSON 데이터에 타입 정보를 포함시켜 역직렬화가 가능하도록 설정

.activateDefaultTyping(typeValidator, DefaultTyping.NON_FINAL)

 

 

3) Java의 날짜/시간 타입을 Jackson에서 직렬화/역직렬화할 수 있도록 설정

.registerModule(new JavaTimeModule())

 

 

 

| 결과

 

 

 

  • Redis에 LocalDateTime 데이터를 정상적으로 저장하고 역직렬화하여 출석체크 페이지가 동작하는 것을 확인함.
  • JSON 데이터를 다룰 때 Jackson 모듈 관리와 타입 정보 포함의 중요성을 학습함.