第一步:
第二步:
第三步:RedisHttpSessionConfiguration类中注入了 RedisTemplate
第三步里,只设置了key的序列化方式,没有设置value的序列化方式,所以如果value是一个对象,且没有实现Serializable接口的话,存到redis里会报错。所以使用默认的序列化方式的话,对象必须实现Serializable接口
org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to
serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type
[com.cicdi.servertemplate.modules.vote.model.VoteSubjectHoptTotalVoteNum]
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:93)
at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:171)
at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129)
at com.cicdi.servertemplate.common.util.RedisUtil.hmset(RedisUtil.java:293)
....................省略....................
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is
java.lang.IllegalArgumentException: Default Serializer requires a Serializable payload but received an object of type [com.cicdi.servertemplate.modules.vote.model.VoteSubjectHoptTotalVoteNum]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68)
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35)
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:91)
... 135 more
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type
[com.cicdi.servertemplate.modules.vote.model.VoteSubjectHoptTotalVoteNum]
at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43)
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63)
... 137 more
第四步:自定义配置类RedisConfig中再次注入RedisTemplate,这里的 RedisTemplate 经过了个性化设置,设置其key是string类型、value是json串,这样存到redis里的时候就不会报错了。
如果不重新注入 RedisTemplate 自定义配置,存到redis里的key是乱码的,但是RedisHttpSessionConfiguration类中注入的 RedisTemplate 其实已经设置了key为string类型的,为什么用默认的就会乱码呢??
配置类:
@Configuration + @Bean 相当于重新注入类,所以断点会进到这里来
完整配置类:
@Configuration
public class RedisConfig {
@Value("${spring.redis.password}")
public String password;
@Value("${spring.redis.host}")
public String host;
// *****************************上**********************************
@Bean
public CachingConfigurerSupport keyGenerator() {
return new MyCachingConfigurerSupport();
}
public class MyCachingConfigurerSupport extends CachingConfigurerSupport {
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}
// TODO: 2019/9/6 SpringCacheRoleHierarchy和SpringCacheModuleSecurity存储的缓存还是乱码
// //缓存管理器
// @SuppressWarnings("rawtypes")
// @Bean
// public CacheManager cacheManager(StringRedisTemplate redisTemplate) {
// RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
// //设置缓存过期时间
// rcm.setDefaultExpiration(1800);//秒
// return rcm;
// }
// *******************************下********************************
/**
* 存入对象tostring后的信息
* 修改默认序列化方式
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate template = new RedisTemplate<>();
// template.setConnectionFactory(jedisConnectionFactory());
template.setConnectionFactory(connectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX
template.setHashKeySerializer(stringRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
// /**
// * 使用SpringSession里的 @EnableRedisHttpSession(redisNamespace = "jscmp") 注解
// * 该注解开启了redis连接
// */
// @Bean
// JedisConnectionFactory jedisConnectionFactory() {
// JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
// jedisConnectionFactory.setHostName(host);
// jedisConnectionFactory.setPassword(password);
// return jedisConnectionFactory;
// }
/**
* 解决redis集群环境没有开启Keyspace notifications导致的
*
* Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource
*
* */
@Bean
public static ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}
}