본문 바로가기

개발중/Spring Boot & Redis

Spring boot 3.2.2 & Redis & GenericJackson2JsonRedisSerializer

728x90
반응형

 

Spring Boot 2 에서 Spring Boot 3 으로 마이그레이션 하면서 Redis 역/직렬화 이슈가 발생하였습니다.

 

아래 문서를 읽고 기존에 사용하던 Jackson2JsonRedisSerializer 라이브러리를 GenericJackson2JsonRedisSerializer  라이브러리로 교체하였습니다.

 

https://docs.spring.io/spring-session/reference/configuration/redis.html

 

Jackson2JsonRedisSerializer  라이브러리 주석

 

GenericJackson2JsonRedisSerializer 

 

GenericJackson2JsonRedisSerializer 클래스는 Spring Data Redis에서 제공하는 RedisSerializer의 구현체 중 하나로, Java 객체를 JSON으로 직렬화하거나 JSON을 Java 객체로 역직렬화하는 데 사용됩니다. 이 직렬화기는 Jackson 라이브러리를 기반으로 합니다.

 

GenericJackson2JsonRedisSerializer의 특징

유연성

이 직렬화기는 ObjectMapper를 사용하여 객체를 JSON으로, JSON을 객체로 변환합니다. 

사용자가 직렬화 과정에서 사용할 ObjectMapper를 커스터마이즈 할 수 있어 다양한 설정을 적용할 수 있는 유연성을 제공합니다.

타입 정보 저장

기본 설정에서, GenericJackson2JsonRedisSerializer는 객체의 클래스 타입 정보를 JSON에 저장합니다. 이는 역직렬화 시 정확한 타입으로 객체를 복원할 수 있도록 도와주지만, JSON의 크기를 증가시킬 수 있습니다. 필요에 따라 이 기능을 비활성화할 수도 있습니다.

보안 설정

기본적으로 이 직렬화기는 타입 정보를 사용하여 역직렬화를 수행할 때 특정 클래스 타입으로의 역직렬화를 제한하여 보안 위험을 감소시킵니다. 예를 들어, 알려지지 않은 타입으로의 역직렬화 시도를 차단할 수 있습니다.

 

GenericJackson2JsonRedisSerializer를 사용하는 예는 다음과 같습니다. Spring에서 RedisTemplate 설정 시 이 직렬화기를 사용할 수 있습니다.

 

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

    GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
    template.setValueSerializer(serializer);
    template.setHashValueSerializer(serializer);

    template.setKeySerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new StringRedisSerializer());

    template.afterPropertiesSet();
    return template;
}

 

 

이 설정은 모든 Redis 값에 대해 JSON 형태로 직렬화를 수행하도록 설정합니다. 

키에 대해서는 StringRedisSerializer를 사용하여 문자열로 직렬화합니다.

GenericJackson2JsonRedisSerializer 주의 사항

성능과 저장 공간

JSON 직렬화는 바이너리 직렬화에 비해 CPU 자원을 더 많이 사용하며, 저장 공간도 더 많이 필요할 수 있습니다. 직렬화된

데이터의 크기가 중요한 경우 다른 직렬화 방법을 고려할 수 있습니다.

 

역직렬화 문제

클래스 타입 정보가 변경되거나 삭제되었을 때 역직렬화 과정에서 오류가 발생할 수 있습니다. 이는 클래스 정의가 변경된 경우에 특히 문제가 될 수 있습니다.
GenericJackson2JsonRedisSerializer는 매우 유용하지만, 사용 사례에 따라 적절한 설정과 관리가 필요합니다.

 

 

GenericJackson2JsonRedisSerializer 을 활용하여 직렬화와 역직렬화하는 방법

public void saveDataToRedis(String key, SomeObject data) {
    redisTemplate.opsForValue().set(key, data);
}

public SomeObject fetchDataFromRedis(String key) {
    return (SomeObject) redisTemplate.opsForValue().get(key);
}

 

 

GenericJackson2JsonRedisSerializer 고급 설정 및 사용자 정의

GenericJackson2JsonRedisSerializer는 내부적으로 ObjectMapper를 사용합니다. 기본 생성자 외에도 사용자 정의 ObjectMapper를 인자로 받는 생성자를 제공하여, 직렬화 및 역직렬화 동작을 더 세밀하게 제어할 수 있습니다.

사용자 정의 ObjectMapper 설정 예제

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

    // ObjectMapper 사용자 정의
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  // 타입 정보 포함 설정
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);  // 날짜와 시간 형식 설정
    objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

    GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper);

    template.setValueSerializer(serializer);
    template.setHashValueSerializer(serializer);
    template.setKeySerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new StringRedisSerializer());

    template.afterPropertiesSet();
    return template;
}

 

참고문서

 

https://github.com/spring-projects/spring-data-redis/blob/main/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java

 

spring-data-redis/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java at main · spr

Provides support to increase developer productivity in Java when using Redis, a key-value store. Uses familiar Spring concepts such as a template classes for core API usage and lightweight reposito...

github.com

 

728x90
반응형