报错提示
org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: 3139322E
原因
SpringBoot使用spring-data-redis,RedisTemplate默认的序列化方式是用org.springframework.data.redis.serializer.JdkSerializationRedisSerializer这个类来做序列化,而Redis有自己的序列化方式,所以冲突了 报出了上面的序列化异常的信息。
从RedisTemplate源码中找到了原因:
解决
在使用到redisTemplate的类中加入下面的配置,指定使用的序列化方式:
将key序列化方式改为 StringRedisSerializer,将value序列化方式改为 GenericJackson2JsonRedisSerializer 。
private RedisTemplate<String, QuestionTemplate> redisTemplate;
//指定用redis的序列化方式进行序列化
@Autowired(required = false)
public void setRedisTemplate(RedisTemplate redisTemplate) {
RedisSerializer stringSerializer = new StringRedisSerializer();//序列化为String
//不能反序列化
//Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//序列化为Json
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(serializer);
this.redisTemplate = redisTemplate;
}
注意:Jackson2JsonRedisSerializer可以序列化成功,但是反序列化会失败,所以建议用GenericJackson2JsonRedisSerializer即可序列化也可反序列化。
1、由Jackson2JsonRedisSerializer 序列化产生的格式:
2、由GenericJackson2JsonRedisSerializer 序列化产生的格式:
由序列化冲突导致的问题有:
1、redis数据库有值, 但是用redisTemplate根据key获取value值为 null
2、存入redis数据库中字符乱码,字符串前缀出现\xac\xed\x00\x05t\x00\x10(但是不影响读写)
3、序列化和反序列化失败
参考文章:
springboot集成redis时报错
SpringBoot集成Redis,并自定义对象序列化
RedisTemplate操作redis时,key值出现\xac\xed\x00\x05t\x00前缀