Springboot+Redis序列化坑
今天在测试springboot整合redis的时候遇到下面这个坑,百度来百度去发现提示都是ajax的问题,真的是醉了,错误提示如下所示,不信大家可以直接复制百度一下答案是什么(流泪中。。。。),错误如下:
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized token 'b4811c63': was expecting ('true', 'false' or 'null')
1.错误原因排查
然后就进行debug调试,发现代码一直到redisTemplate.opsForZSet().reverseRangeWithScores()这一行都没问题,然后进入redis源代码里面检查,发现是在发送redis服务的时候出现问题,所以可以断定应该是配置的问题,然后仔细检查配置,发现也没有错误,redis序列化的配置如下所示:
@Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new StringRedisTemplate(factory); 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); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
2.细节分析
这一条线索断掉之后,只能通过错误信息来分析了,错误信息中有一条特别奇怪,就是token 'b4811c63',然后我仔细从redis中对比,发现是之前存储的redis的key值,判断可能是redis中key存在乱码,所以就将redis的key全部清空,自己添加数据进去,发现自己添加的数据是可以的。从这一现象可以得出,应该实现老系统序列化的规则和现在springboot的序列化规则不一样导致的,查看老系统的redis配置信息,如下所示:
<!--序列化--> <bean name="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <bean name="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> <bean id="clusterRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="redis4CacheConnectionFactory"/> <property name="keySerializer" ref="stringRedisSerializer"/> <property name="hashKeySerializer" ref="stringRedisSerializer"/> <property name="valueSerializer" ref="stringRedisSerializer"/> <property name="hashValueSerializer" ref="stringRedisSerializer"/> </bean>
3.问题解决
然后和我们刚才序列化的方式对比一下,发现真的是序列化方式不一样,旧的是通过StringRedisSerializer进行序列化的,springboot是通过Jackson2JsonRedisSerializer进行序列化的。所以为了兼容老系统的序列化方式,这边我将springboot也改成StringRedisSerializer的序列化方式,代码如下所示:
@Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new StringRedisTemplate(factory); StringRedisSerializer stringRedisSerializer =new StringRedisSerializer(); redisTemplate.setValueSerializer(stringRedisSerializer); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); redisTemplate.setHashValueSerializer(stringRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
改完之后,发现这个问题就没有了,redis中就可以照常插入、查询数据了。
总结:
这个问题是很典型的架构优化问题,老系统和新系统代码兼容性问题。从这个坑可以得出这样的结论:百度得到的答案很大一部分都是片面的,我们还是得根据实际情况来分析。其次就是要仔细看报错信息,不要放过一点细节,因为可能你的答案就在这一点细节中。
相关文章
- Redis(十七)-SpringBoot集成Redis
- Redis事件处理机制详解
- Redis哨兵主备切换的数据丢失问题
- 带你掌握Redis数据类型:string和Hash
- springboot:DevTools导致读取redis时发生类型转换错误
- 牛逼!Redis 的字符串是这样实现的…
- springboot整合redis——redisTemplate的使用
- SpringBoot之Redis访问(spring-boot-starter-data-redis)
- Redis学习之5种数据类型操作、实现原理及应用场景
- Redis之快速入门与应用[教程/总结]
- springboot中各个版本的redis配置问题
- redis学习笔记
- redis主从复制原理、搭建、以及如何规避复制风暴和全量复制
- redis——sentinel
- SpringBoot中如何解决Redis的缓存穿透、缓存击穿、缓存雪崩?
- windows安装redis服务端和客户端,springboot使用
- 【redis入门系列】初识 redis以及redis的安装
- 利用Redis原子计数器incr实现计数器及接口限流
- SpringBoot 使用 Redis Geo
- SpringBoot使用@Cacheable实现最简单的Redis缓存
- redis错误总结