Redis 多项目序列化问题
Redis序列化问题
主要会出现一下问题:
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 java.io.InvalidClassException: com.ninebot.apr.global.beans.data.AreaNoticeInfo; class invalid for deserialization
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 java.io.InvalidClassException: com.ninebot.apr.global.beans.data.AreaNoticeInfo; class invalid for deserialization
原因:
Redis客户端未指定序列化的方式,默认为JdkSerializationRedisSerializer序列化操作
JdkSerializationRedisSerializer:这个在多项目中反序列化会出现一个问题,反序列化的对象Bean必须与序列化对象是相同的包名才能匹配,不然出现上述问题。
解决方案:
- 建立相同包名的对象
- 改变序列化方式
Redis目前支持的序列化方式
-
JdkSerializationRedisSerializer
序列化java对像的、被序列化的对象必须实现Serializable接口
在存储内容时,除了属性的内容外还存了其它内容在里面,总长度长,且不容易阅读
跨项目使用比较容易出现问题,两边对象必须具有相同的包名
他存储的为二进制数据
,这对开发者是不友好的 -
GenericJackson2JsonRedisSerializer(不用指定class类型)
、JacksonJsonRedisSerializer
类似
序列化object对象为json字符串并保存到redis中,但需要和jackson配合一起使用
被序列化的对象不用实现Serializable接口
Jackson是利用反射和getter和setter方法进行读取的,如果不想因为getter和setter方法来影响存储,就要使用注解来定义被序列化的对象。
Jackson序列化的结果清晰,容易阅读,而且存储字节少,速度快,推荐。
问题:对于LocalDate等一些不太支持会报错
还有那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。 通过查看源代码,发现其在反序列化过程中用到了类型信息(必须根据此类型信息完成反序列化)GenericJackson2JsonRedisSerializer会将属性对象转化为Object,在反序列化时会出现转化问题
-
StringRedisSerializer
简单的字符串序列化,本源所在
不能序列化Bean,只能序列化字符串类型的数据 -
GenericFastJsonRedisSerializer
主要是利用了阿里爸爸的FastJson做转化,会更快
FastJsonRedisSerializer需要指定反序列化类型,而GenericFastJsonRedisSerializer则比较通用
处理List、Set、Long类型等可能会出现问题