记一次SpringBoot项目使用RedisTemplate无法反序列化字节数组问题困扰8小时巨坑

一、问题描述

问题描述:
前提:向RedisSET值的是一个JFinal项目,使用的Jedis客户端API操作的,把一个对象转成byte[]形式存入Redis中。
然后在另一个SpringBoot项目中我通过Spring自带的RedisTemplate对象来获取,一直失败。
接下来就是我的踩坑记录:

在这里插入图片描述

二、踩坑记录

使用StringRedisTemplate获取值(即采用StringRedisSerializer序列化方式)
在这里插入图片描述

然后我使用命令行获取去发现返回同样是乱码:
在这里插入图片描述

又换成Jackson2JsonRedisSerializer进行反序列化,还是报错,JSON反序列化失败:
在这里插入图片描述
使用FastJson反序列化也还是失败:
在这里插入图片描述
使用默认的序列化方式,还是失败:
在这里插入图片描述

三、黎明前夕

因为Redis中存储的值是字节数组,所以使用的就是默认的Jdk序列化方式。
现在重要的就是怎么反序列化的?
解铃还须系铃人
要想反序列化成功,就必须知道序列化是什么形式,
分析源码:从Jfinal项目入手,查看了Jedis客户端的set和get方法API,发现了使用的序列化方式是:FstSerializer
在这里插入图片描述
在这里插入图片描述
在set和get方法中使用了valueFromBytes和valueToBytes两个方法:
即:
valueToBytes方法:将对象序列化为一个字节数组。
valueFromBytes方法:将字节数组反序列化为原来的对象。

在继续深入源码发现使用的序列化和反序列化方式为 FstSerializer
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在研究get方法的反序列化过程:
在这里插入图片描述
核心代码即:

FSTObjectInput fstInput = null;
try {
	fstInput = new FSTObjectInput(new ByteArrayInputStream(bytes));
	return fstInput.readObject();
}

所以我们就知道了序列化方式和反序列化的方法!

从Maven仓库中找到这个依赖:

      <!-- https://mvnrepository.com/artifact/de.ruedigermoeller/fst -->
      <dependency>
          <groupId>de.ruedigermoeller</groupId>
          <artifactId>fst</artifactId>
          <version>2.57</version>
      </dependency>

然后从Redis中取出字节数组,在按照反序列化方法还原出原来对象:

//定义get方法,返回字节数组形式的Value
    public byte[] get(byte[] key) {
        return (byte[]) redisTemplate.execute((RedisCallback<byte[]>) redisConnection -> {
            // 传入byte[]类型的key,获取byte[]类型的value
            byte[] bytes = redisConnection.get(key);
            return bytes;
        });
    }

然后进行反序列化:

 byte[] bytes = get(redisKey.getBytes());
 FSTObjectInput fstInput = new FSTObjectInput(new ByteArrayInputStream(bytes));;
 SiBean redisSi =  (SiBean)fstInput.readObject();

然后到此一位就大功告成了,但是又出现了最后一个Bug!!
在这里插入图片描述
报错信息提示没有找到这个Class。由于在向Redis中存值的时候直接是一个对象转字节数组,所以字节数组中包含对象的完整类名信息,所以我们还需要再相同的包路径下创建对应的对象,还有一点需要注意:这个对象需要实现Jdk的序列化接口:
在这里插入图片描述

四、成功解决

解决方法:

  1. 使用JdkSerializationRedisSerializer序列化方式接收字节数组。
  2. 使用FSTObjectInput对象将字节数组反序列化。
  3. 对象全类名要保持一致,并且实现序列化接口
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liu_Shihao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值