在我的REST控制器Spring项目中,我想在Redis中存储会话信息。
在我的 application.properties 中,我定义了以下内容:
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
我还启用了Http Redis Session:
@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer
{}
我终于有了这样的redis连接工厂:
@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;
}
}
使用此配置,会话信息存储在Redis中,但是,它被非常奇怪地序列化。我的意思是,密钥是可读的,但存储的值不是(我从名为“Redis桌面管理器”的程序查询信息)...例如...对于新会话,我得到一个带密钥的哈希: / p>
*spring:session:sessions:c1110241-0aed-4d40-9861-43553b3526cb*
此哈希包含的键是:maxInactiveInterval,lastAccessedTime,creationTime,sessionAttr:SPRING_SECURITY_CONTEXT 但是他们的价值就像他们所说的那样:
\ XAC \ XED \ X00 \ x05sr \ X00 \ x0Ejava.lang.Long; \ x8B \ XE4 \ X90 \ XCC \ X8F#\ XDF \ X02 \ X00 \ x01J \ X00 \ x05valuexr \ X00 \ x10java.lang。数\ 86 \ XAC \ X95 \ X1D \ X0B \ X94 \ xE0 \ x8B \ X02 \ X00 \ x00xp \ X00 \ X00 \ X01B $ G \ X88 *
(对于creationTime键)
如果我尝试使用redisTemplate从代码中访问此信息,则会出现类似这样的异常:
目标VM发生异常:无法反序列化;嵌套异常是 org.springframework.core.serializer.support.SerializationFailedException: 无法反序列化有效负载。字节数组是否是结果 DefaultDeserializer的相应序列化?嵌套异常 是java.io.StreamCorruptedException:无效的流标题:73657373 org.springframework.data.redis.serializer.SerializationException:无法反序列化;嵌套异常是 org.springframework.core.serializer.support.SerializationFailedException: 无法反序列化有效负载。字节数组是否是结果 DefaultDeserializer的相应序列化?嵌套异常 是java.io.StreamCorruptedException:无效的流标题:73657373 在org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:82)
我认为Spring会话信息的序列化/反序列化存在某种问题,但我不知道还能做些什么才能控制它。
有谁知道我做错了什么?
谢谢
答案 0 :(得分:0)
您步入正轨,您的问题确实是序列化。尝试以下配置(仅使用这些序列化器配置模板):
template.setHashValueSerializer(new JdkSerializationRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
template.setDefaultSerializer(new JdkSerializationRedisSerializer());