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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 您好,我是码农飞哥,感谢您阅读本文!最近在进行框架改造,历史遗留代码对Redis的使用不当,导致了一些问题。

您好,我是码农飞哥,感谢您阅读本文!最近在进行框架改造,历史遗留代码对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)

从问题的描述我们就可以轻松的定位到这是由于调用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);
        });
    }

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

88acfca4e1946093fa0b8b072ea31990_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ1MzQ4MDg=,size_16,color_FFFFFF,t_70.png

正确的姿势

对于历史的记录,只能在报错之后删除掉该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;
    }

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

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


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
66 6
|
1月前
|
JSON 缓存 NoSQL
Redis 在线查看序列化对象技术详解
Redis 在线查看序列化对象技术详解
37 2
|
1月前
|
Python
通过 type 和 object 之间的关联,进一步分析类型对象
通过 type 和 object 之间的关联,进一步分析类型对象
56 3
|
2月前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
2月前
|
JSON 缓存 NoSQL
redis序列化数据时,如何包含clsss类型信息?
通过配置 `com.fasterxml.jackson.databind.ObjectMapper` 的 `enableDefaultTyping` 方法,可以使序列化后的 JSON 包含类信息。
52 2
|
3月前
|
Docker 容器
成功解决:Caused by: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but
这篇文章讨论了在使用Docker启动Elasticsearch容器时遇到的一个具体问题:由于配置文件`elasticsearch.yml`解析出错导致容器启动失败。文章提供了详细的排查过程,包括查看容器的日志信息、检查并修正配置文件中的错误(特别是空格问题),并最终成功重新启动了容器。
|
3月前
|
NoSQL 数据可视化 Linux
2022 年超详细步骤讲解 CentOS 7 安装Redis 。解决Redis Desktop Manager 图形化工具连接失败解决 ;connection failed处理。开机自启Redis
这篇文章提供了在CentOS 7上安装Redis的详细步骤,包括上传Redis安装包、解压安装、编译、安装、备份配置文件、修改配置以支持后台运行和设置密码、启动Redis服务、使用客户端连接Redis、关闭Redis服务、解决Redis Desktop Manager图形化工具连接失败的问题、设置Redis开机自启动,以及Redis服务的启动和停止命令。
2022 年超详细步骤讲解 CentOS 7 安装Redis 。解决Redis Desktop Manager 图形化工具连接失败解决 ;connection failed处理。开机自启Redis
|
3月前
|
JSON 数据格式 Python
【python】解决json.dump(字典)时报错Object of type ‘float32‘ is not JSON serializable
在使用json.dump时遇到的“Object of type ‘float32’ is not JSON serializable”错误的方法,通过自定义一个JSON编码器类来处理NumPy类型的数据。
153 1
|
3月前
|
XML 缓存 API
【Azure API 管理】使用APIM进行XML内容读取时遇见的诡异错误 Expression evaluation failed. Object reference not set to an instance of an object.
【Azure API 管理】使用APIM进行XML内容读取时遇见的诡异错误 Expression evaluation failed. Object reference not set to an instance of an object.
|
4月前
|
JSON 前端开发 数据格式
【Python】已解决:TypeError: Object of type JpegImageFile is not JSON serializable
【Python】已解决:TypeError: Object of type JpegImageFile is not JSON serializable
88 0
下一篇
无影云桌面