Redis序列化
什么是序列化
本质:
将一种数据结构转为另外一种数据格式
序列化方式:
- JSON 序列化的结果是一个字符串、便于人类阅读和理解
- Protobuf 序列化的结果是紧凑的二进制格式,体积更小、性能更高,但不易于人类阅读
为什么要序列化
- Redis存储只能识别两种格式:字符串、二进制
- 统一格式:跨平台、跨语音
- 节省存储空间,提高传输效率
如果没有自定义序列化方式
如果Redis中没有自定义序列化方式,并不等于不使用序列化方式,而是会使用RedisTemplate模板自带的JdkSerializationRedisSerializer序列化方式:会添加一个"魔数" 前缀,导致非常不便于阅读

通过redis客户端查看能看到前缀,在程序中访问时其本身也是有前缀的,只是JDK序列化协议帮我们自动处理了
redisUtil.setCacheObject("redis", "001");
return redisUtil.getCacheObject("redis");
自定义序列化方式
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// key的序列化采用StringRedisSerializer
// 虽然redis的key的类型只支持字符串,但如果此处不进行字符串序列化,则会执行默认的jdk序列化:十六进制表示
StringRedisSerializer serializer = new StringRedisSerializer();
template.setKeySerializer(serializer);
template.setHashKeySerializer(serializer);
// value值的序列化采用fastJsonRedisSerializer (具体情况具体分析)
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
return template;
}
}
记录一次反序列遇到的问题
问题描述
想模拟项目中的redis序列化方式,相关RedisConfig配置、自定义序列化及反序列化类、Redis工具类等都是直接Copy的,可就是无法将redis中的对象反序列化出来。
TDevicePropertyReport tDevicePropertyReport = redisUtil.getCacheObject(key);
可生成环境却正常运行!!!
一直想的是会不会有什么配置漏了,直到发现Redis中的存储内容,一切都明白了

问题的本质
Redis序列化的时候是会将对象的类型一起进行存储的,并且是完整记录了该对象的存储路径
所以存的时候对象路径和取的时候对象路径一定要一致。(我的问题就是对象路径不一致)
解决方案
方案一
更改对象路径配置:该方式可以存也可以取
方案二
该方式只能取,不能存;因为路径不一致,存新对象的话会导致原本系统无法反序列化
(2025.07.17)但好像这个方法就不要求java实体的具体存储路径了,似乎是更优解
public void contextLoads() {
Collection<String> keys = redisUtil.keys("device_report:".concat("*"));
for (String key : keys) {
JSONObject cacheObject = redisUtil.getCacheObject(key);
TDevicePropertyReport tDevicePropertyReport = JSON.parseObject(cacheObject.toJSONString(), TDevicePropertyReport.class);
System.out.println(tDevicePropertyReport.getCarNum());
}
}
参考链接
【2】Redis反序列化问题
【3】Redis序列化问题



浙公网安备 33010602011771号