一、spring boot 集成Redis方法
- 依赖
<!--redis--><dependency> ???<groupId>org.springframework.boot</groupId> ???<artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency> ???<groupId>org.apache.commons</groupId> ???<artifactId>commons-pool2</artifactId></dependency>
- Redis自定义序列化
@Configurationpublic class RedisConfig { ???@Bean(name = "strRedisTemplate") ???public RedisTemplate<String, String> strRedisTemplate(RedisConnectionFactory factory) { ???????RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); ???????redisTemplate.setConnectionFactory(factory); ???????// 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化) ???????Jackson2JsonRedisSerializer<Object> 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); ???????redisTemplate.setKeySerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); ???????return redisTemplate; ???} ???@Bean(name = "intRedisTemplate") ???public RedisTemplate<String, Integer> intRedisTemplate(RedisConnectionFactory factory) { ???????RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<>(); ???????redisTemplate.setConnectionFactory(factory); ???????// 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化) ???????Jackson2JsonRedisSerializer<Object> 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); ???????redisTemplate.setKeySerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); ???????return redisTemplate; ???}}
- 使用代码
@Servicepublic class RedisServiceImpl implements IRedisService { ???@Resource(name = "intRedisTemplate") ???private RedisTemplate<String, Integer> intTemplate; ???@Resource(name = "strRedisTemplate") ???private RedisTemplate<String, String> strTemplate; ???@Override ???public void incrHash(String key, String field, Integer value) { ???????intTemplate.opsForHash().increment(key, field, value); ???} ???@Override ???public void incrKey(String key, Integer value) { ???????if(null == key || null == value){ ???????????return; ???????} ???????intTemplate.opsForValue().increment(key,value); ???} ???@Override ???public Integer getInteger(String key) { ???????if(null == key){ ???????????return null; ???????} ???????return intTemplate.opsForValue().get(key); ???}}
五、出现问题
使用的时候,发现一个问题,如果我用IntegerTemplate存储值到Redis,会进行序列化,自动为String类型的键和值添加双引号,这是Jackson2JsonRedisSerializer特性,但是使用StringTemplate,存储的String类型的键和值都不带双引号
六、几种序列化对比
这是别人总结的Redis常见的几种序列化方式特性,详细见:参考文章
以下内容引用别人博客
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我们这里针对StringRedisSerializer,Jackson2JsonRedisSerializer和JdkSerializationRedisSerializer进行测试。
下面是,把3种Serializer保存到Redis中的结果:
1,所有的KeySerializer和HashKeySerializer都使用StringRedisSerializer,用其它Serializer的没有什么意义,就像最上面的例子一样。
2,上面序列化后的值,是保存到redis中的值,从Redis中读取回Java中后,值的内容都是一样的。
从上面的结果不难看出,
1,用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的
2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。
3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。对于Hash的Value来说,比Java的内容多了一些字符。
(如果Key的Serializer也用和Value相同的Serializer的话,在Redis中保存的内容和上面Value的差异是一样的,所以我们保存时,只用StringRedisSerializer进行序列化)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
七、问题原因
出现“存储Integer类型数据,自动序列化(加双引号),存储String类型,序列化失败(没有双引号)”的原因是:
我在设置自定义序列化的时候,为Bean起了个名称叫:"StringRedisTemplate",这个名称和StringRedisTemplate重名了,spring注入的时候,注入的是StringRedisTemplate,不是我更改过序列化方式后的Template对象。
@Bean(name = "stringRedisTemplate") ???public RedisTemplate<String, String> strRedisTemplate(RedisConnectionFactory factory) { ???????RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); ???????redisTemplate.setConnectionFactory(factory); ???????// 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化) ???????Jackson2JsonRedisSerializer<Object> 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); ???????redisTemplate.setKeySerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer); ???????redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); ???????return redisTemplate; ???}
真是个傻逼错误
redis使用Jackson2JsonRedisSerializer序列化问题
原文地址:https://www.cnblogs.com/donfaquir/p/10594199.html