Redis序列化
什么是序列化
- JSON 序列化的结果是一个字符串、便于人类阅读和理解
- Protobuf 序列化的结果是紧凑的二进制格式,体积更小、性能更高,但不易于人类阅读
为什么要序列化
- 使用RedisTemplate模板就一定需要序列化,只是选择哪种序列化的问题
- 方便阅读
- 节省存储空间,提高传输效率
如果没有自定义序列化方式
没有自定义序列化方式,不等于不使用序列化方式,而是会使用RedisTemplate模板自带的JdkSerializationRedisSerializer序列化方式:十六进制字符串,极大不便于阅读
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序列化的时候是会将对象的类型一起进行存储的,并且是完整记录了该对象的存储路径
所以存的时候对象路径和取的时候对象路径一定要一致。(我的问题就是对象路径不一致)
解决方案
方案一
更改对象路径配置:该方式可以存也可以取
方案二
该方式只能取,不能存;因为路径不一致,存新对象的话会导致原本系统无法反序列化
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序列化问题