0

In my REST controllers Spring project, I want to store Session information in Redis.

In my application.properties I have defined the following:

spring.session.store-type=redis
spring.session.redis.namespace=rdrestcore

com.xyz.redis.host=192.168.201.46
com.xyz.redis.db=0
com.xyz.redis.port=6379
com.xyz.redis.pool.min-idle=5

I also have enabled Http Redis Session with:

@Configuration
@EnableRedisHttpSession 
public class SessionConfig extends AbstractHttpSessionApplicationInitializer 
{}

I finally have a redis connection factory like this:

@Configuration
@EnableRedisRepositories
public class RdRedisConnectionFactory {
    @Autowired 
    private Environment env;
    @Value("${com.xyz.redis.host}")
    private String redisHost;
    @Value("${com.xyz.redis.db}")
    private Integer redisDb;
    @Value("${com.xyz.redis.port}")
    private Integer redisPort;
    @Value("${com.xyz.redis.pool.min-idle}")
    private Integer redisPoolMinIdle;

    @Bean
    JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();        
        if(redisPoolMinIdle!=null) poolConfig.setMinIdle(redisPoolMinIdle);

        return poolConfig;
    }

    @Bean    
    JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory jedisConFactory = new JedisConnectionFactory();
        if(redisHost!=null) jedisConFactory.setHostName(redisHost);
        if(redisPort!=null) jedisConFactory.setPort(redisPort);
        if(redisDb!=null) jedisConFactory.setDatabase(redisDb);
        jedisConFactory.setPoolConfig(jedisPoolConfig());
        return jedisConFactory;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        final RedisTemplate< String, Object > template =  new RedisTemplate();
        template.setConnectionFactory( jedisConnectionFactorySpring());
        template.setKeySerializer( new StringRedisSerializer() );
        template.setValueSerializer( new GenericJackson2JsonRedisSerializer() );
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer( new GenericJackson2JsonRedisSerializer() );

        return template;
    }
}

With this configuration, the session information gets stored in Redis, but, it is serialized very strangely. I mean, the keys are readable, but the values stored are not (I query the information from a program called "Redis Desktop Manager")... for example... for a new session, I get a hash with key:

*spring:session:sessions:c1110241-0aed-4d40-9861-43553b3526cb*

and the keys this hash contains are: maxInactiveInterval, lastAccessedTime, creationTime, sessionAttr:SPRING_SECURITY_CONTEXT but their values are all they coded like something similar to this:

\xAC\xED\x00\x05sr\x00\x0Ejava.lang.Long;\x8B\xE4\x90\xCC\x8F#\xDF\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xAC\x95\x1D\x0B\x94\xE0\x8B\x02\x00\x00xp\x00\x00\x01b$G\x88*

(for the creationTime key)

and if I try to access this information from code, with the redisTemplate, it rises an exception like this one:

Exception occurred in target VM: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: 73657373 org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: 73657373 at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:82)

I think it is some kind of problem with the serialization/deserialization of the Spring session information, but I don't know what else to do to be able to control that.

Does anyone know what Im doing wrong?

Thank you

Pep Gomez
  • 197
  • 4
  • 14

1 Answers1

1

You're on the right track, your problem is serialization indeed. Try this configuration (configure your template with these serializers only):

template.setHashValueSerializer(new JdkSerializationRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
template.setDefaultSerializer(new JdkSerializationRedisSerializer());
embuc
  • 465
  • 5
  • 5