Redis序列化的问题:Failed to deserialize object type

举报
码农飞哥 发表于 2021/05/29 12:02:13 2021/05/29
【摘要】 您好,我是码农飞哥,感谢您阅读本文!最近在进行框架改造,历史遗留代码对Redis的使用不当,导致了一些问题。 问题描述 org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframewor...

您好,我是码农飞哥,感谢您阅读本文!最近在进行框架改造,历史遗留代码对Redis的使用不当,导致了一些问题。

问题描述

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 org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: com.coep.model.domain.UserCache
	at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:84)

  
 
  • 1
  • 2

从问题的描述我们就可以轻松的定位到这是由于调用JdkSerializationRedisSerializer的deserialize方法对redis值进行反序列化时报的错。

问题分析

错误提示是ClassNotFoundException: com.coep.model.domain.UserCache,这个UserCache类找不到了,为啥找不到呢,这是由于我们在进行框架改造时变更了类的包名。所以,反序列化类时就找不到了。原有的对redis的操作类。

对redis使用的错误示范

 private static RedisSerializer<Object> jdkRedisSerializer = new JdkSerializationRedisSerializer(); private static RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();

public boolean set(final String key, final Object obj, final long seconds) { // key的组织形式 namespace:id:parmeter strRedisTemplate.execute((RedisCallback<Serializable>) connection -> { final byte[] keyBytes = stringRedisSerializer.serialize(key); final byte[] name = jdkRedisSerializer.serialize(obj); connection.setEx(keyBytes, seconds, name); return null; }); return true; } @Override public Serializable get(final Serializable key) { return strRedisTemplate.execute((RedisCallback<Serializable>) connection -> { byte[] keyBytes = stringRedisSerializer.serialize( key); byte[] bytes = connection.get(keyBytes); return (Serializable) jdkRedisSerializer.deserialize(bytes); }); }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里设置键值时,对key使用的是StringRedisSerializer进行序列化,对value使用的是JdkSerializationRedisSerializer进行序列化。序列化后的数据类型是二进制的字节码文件,可视性差。而且使用JdkSerializationRedisSerializer序列化性能比较差,所以不推荐使用。
在这里插入图片描述

正确的姿势

对于历史的记录,只能在报错之后删除掉该key。这里推荐使用StringRedisSerializer来序列化key和value。相关的配置如下:
使用RedisTemplate操作类的配置如下:

  @Primary @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { try { //测试连通性 factory.getConnection(); } catch (RedisConnectionFailureException e) { LOGGER.warn("未发现redis服务。"); redisAvailable = false; } RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setConnectionFactory(factory); return redisTemplate; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

或者直接使用StringRedisTemplate操作类的配置如下:

  @Bean public StringRedisTemplate stringRedisTemplate(JedisConnectionFactory redisConnectionFactory) { StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory); return stringRedisTemplate; }


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。

原文链接:feige.blog.csdn.net/article/details/113242603

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。