关于Springboot 2.x Redis Session 自定义key value序列化方式的误区
程序员文章站
2022-05-01 15:53:37
...
前言
最近做项目用到了spring session,将session保存到redis中,但是保存的数据格式是byte类型,不方便查看。查了相关资料,发现spring session默认使用的redis的JdkSerializationRedisSerializer方式,正是这个原因造成数据格式不友好。于是就想更改一下redis的默认序列化方式。
找了好多资料,网上大都是下面的更改方式,思路不错,但是方式在2.0以上的版本是不对的。
@Bean(name = "redisTemplate")
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
Redis习惯使用 Json格式来存储了,spring-session 2.0 开始网上提供的大部分方法已经都不适用了,查看源码可知,归根结底还是defaultRedisSerializer没有被初始化,导致直接被默认JdkSerializationRedisSerializer初始化。
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (defaultSerializer == null) {
defaultSerializer = new JdkSerializationRedisSerializer(
classLoader != null ? classLoader : this.getClass().getClassLoader());
}
...
........
if (enableDefaultSerializer && defaultUsed) {
Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
}
if (scriptExecutor == null) {
this.scriptExecutor = new DefaultScriptExecutor<>(this);
}
initialized = true;
}
那么到底怎样才能初始化defaultRedisSerializer呢,这里查看RedisHttpSessionConfiguration源码类,查到了一些端倪:
原来是通过该方法创建defaultRedisSerializer的bean的,难怪defaultRedisSerializer一直是null,这里创建一个一样的bean即可。
这里简单介绍一下可行的解决方案:创建一个相同的springSessionDefaultRedisSerializer即可。
/**
* @Title: defaultRedisSerializer
* @Description: TODO(spring session的自定义key value序列化方式)
* @author miki
* @date 2020年9月4日 下午8:50:34
* @throws
*/
@Bean("springSessionDefaultRedisSerializer")
public RedisSerializer<Object> defaultRedisSerializer(){
logger.debug("自定义Redis Session序列化加载成功");
return valueSerializer();
}
private RedisSerializer<Object> valueSerializer() {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(
Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer; //new GenericJackson2JsonRedisSerializer();
}
原文来自:
http://sharehoo.cn/topic/detail/486
上一篇: 打开sqlserver2008提示出错
下一篇: webapi中如何使用依赖注入