I am using RedisCacheManager to store my cache data in my spring-boot application. Default serializer seems to serialize everything into byte and deserialize from byte to appropriate java type.
However, I want to make the cache data be stored as json so that I can read it from none-java clients.
I found that switching from default one to other serializers such as Jackson2JsonRedisSerializer supposed to work. After doing this, deserialization phase fails.
pom.xml
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
CacheConfig.java
@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public RedisConnectionFactory createRedisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName("localhost");
        return factory;
    }
//    SPRING-DATA-REDIS ALREADY PROVIDES A STRING REDIS TEMPLATE, SO THE FOLLOWING IS NOT NECESSARY
//    @Bean
//    public RedisTemplate<String, String> createRedisTemplate(RedisConnectionFactory factory) {
//        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
//        redisTemplate.setConnectionFactory(factory);
//        return redisTemplate;
//    }
    @Bean
    public CacheManager redisCacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        return cacheManager;
    }
}
Is there a way to store them in a pure JSON format and successfully deserialize from it?
add this in your configuration to explicitly set the jackson serializer in redis template.
public @Bean RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
    template.setKeySerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
    template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    return template;
}
                        As of spring-data-jpa:2.0.2.RELEASE at least, configuring the default redis template does not affect how the @Cacheable annotation family accesses redis. Anyway, since I'm using a redis template for more than that, it's not something I want to do.
This, however, isolates the configuration for the cache manager and works as expected:
@Configuration
@EnableCaching
public class RedisCacheManagerConfiguration {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    @Bean
    public CacheManager redisCacheManager() {
        RedisSerializationContext.SerializationPair<Object> jsonSerializer = 
         RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());
         return RedisCacheManager.RedisCacheManagerBuilder
                .fromConnectionFactory(redisConnectionFactory)
                .cacheDefaults(
                    RedisCacheConfiguration.defaultCacheConfig()
                            .entryTtl(Duration.ofDays(1))
                            .serializeValuesWith(jsonSerializer)
                )
                .build();
    }
}
It makes use of the generic Json serializer for Redis (GenericJackson2JsonRedisSerializer).
You can also configure other aspects of the cache manager, such as the time-to-live of the key in redis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With