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中就可以照常插入、查询数据了。

总结:

这个问题是很典型的架构优化问题,老系统和新系统代码兼容性问题。从这个坑可以得出这样的结论:百度得到的答案很大一部分都是片面的,我们还是得根据实际情况来分析。其次就是要仔细看报错信息,不要放过一点细节,因为可能你的答案就在这一点细节中。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/16224.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论