redis反序列化失敗解決方案


一、問題描述:

執行代碼:

valueOperations.set(user1.getUserName() , user1);

將對象存入redis,存入后變成了如下所示的樣子。

 二、原因分析

我們首先在實體類中實現了序列化接口,這時,User對象序列化為了字節流,傳輸進入redis,但是在進入redis反序列化為key和value對象的時候發生了錯誤,因此這里出現此問題是因為redis的反序列化失敗,這時我們就主要圍繞redis反序列化失敗進行研究。

三、解決方案

對redis進行配置,實現發序列化,因為reids序列化已經實現了,這里就不用再對序列化進行研究了(redis序列化見文章:https://www.cnblogs.com/yeyuting/p/14414736.html)。

這里對key和value分別進行反序列化,進而在redis中生成字符型的key和對象型value。

/**
 * @author yeyuting
 * @create 2021/2/19
 */
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(new JdkSerializationRedisSerializer());
        //value hashmap序列化
        template.setHashValueSerializer(redisSerializer);
        //key haspmap序列化
        template.setHashKeySerializer(redisSerializer);

        return template;
        }
    }

執行后redis中是這樣的:

 

 

 可知,key反序列話成功了,但是value對象反序列化失敗了,接着就將注意力轉移到value對象的反序列化中來。

當我們的數據存儲到Redis的時候,我們的鍵(key)和值(value)都是通過Spring提供的Serializer序列化到數據庫的。RedisTemplate默認使用的是JdkSerializationRedisSerializer,StringRedisTemplate默認使用的是StringRedisSerializer。 用JdkSerializationRedisSerializer序列化的話,被序列化的對象必須實現Serializable接口。在存儲內容時,除了屬性的內容外還存了其它內容在里面,總長度長,且不容易閱讀。我們要求是存儲的數據可以方便查看,也方便反系列化,方便讀取數據。JacksonJsonRedisSerializer和GenericJackson2JsonRedisSerializer,兩者都能系列化成json,但是后者會在json中加入@class屬性,類的全路徑包名,方便反系列化。前者如果存放了List則在反系列化的時候如果沒指定TypeReference則會報錯java.util.LinkedHashMap cannot be cast to 。

因此保險起見,我們將JdkSerializationRedisSerializer換成GenericJackson2JsonRedisSerializer,修改后的代碼如下:

/**
 * @author yeyuting
 * @create 2021/2/19
 */
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //value hashmap序列化
        template.setHashValueSerializer(redisSerializer);
        return template;
        }
    }

執行后redis緩存內容正常顯示,如下:

 

 至此,結束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM