SpringBoot項目使用RedisTemplate遇到key值\xac\xed\x00\x05t\x00的坑

  前端時間新項目使用SpringBoot的RedisTemplate遇到一個問題,先簡單描述一下問題:不一樣項目之間redis共用一個,可是咱們新項目讀不到老項目存儲的緩存。新項目搭建的時候沒有跟老項目使用同一個core包裏的redisutils工具類,老項目使用的是jedis對象來操做redis,新項目使用了springboot封裝的redistemplate,代碼上存在差別因此出現問題也就很正常,先來看一下新項目裏對redistemplate的使用:(截取一個方法爲例)前端

  現象:redis

  

   能夠看出來工具直接注入spring容器中的redistemplate,沒有指定泛型,在使用的時候經過key的泛型使用的是Serializable,value的泛型是value,從泛型能看出來key跟泛型有必定關係,下面就來驗證一下爲何取不到值。咱們先往redis裏存儲一個緩存以字符串爲例:spring

  

   寫一個junit測試 緩存

  

   測試取緩存springboot

  

   經過結果發現沒有取到值,反過來經過測試方法存一下緩存,再看咱們存的是一個什麼值工具

  

   經過結果發現咱們存進去的key是redistemplate-test,可是redis實際存進去的key倒是\xac\xed\x00\x05t\x00\x12redistemplate-test,同理,咱們取緩存的時候前面也會自動加上一串看不懂的東西,因此取值的時候確定也取不出來。作項目的時候時間比較緊,用了其餘同事的代碼保證項目上線,上線後纔回過頭去看取不到值的緣由,其實同事的代碼也很簡單,只是在使用redistemplate的時候指定了泛型爲string,就能夠取到值了,其實也可使用StringRedisTemplate來操做,可是StringRedisTemplate主要用來存儲字符串,它的泛型指定的是String。若是存入對象時,會報錯 :can not cast into String,因此咱們就繼續修改這個工具,解決key值前面的字符串。測試

   緣由:spa

  下面咱們簡單的看一下redistemplate源碼3d

  

  opsForValue方法會返回一個ValueOperations<K, V>,k跟v就是泛型,咱們就是經過valueOps來get,set咱們的值。這個方法會new一個DefaultValueOperations對象,傳入的template就是當前RedisTemplate對象,向下看:對象

   有不少個RedisSerializer,默認都是null,當調用opsForValue方法時會傳入當前redistemplate對象,以keySerializer爲例,它默認爲null,若是等於null就被賦值dafaultSerializer,默認dafaultSerializer也爲空,最終keySerializer就被賦值爲JdkSerializationRedisSerializer,因此沒有設置序列化方式的時候redistemplate使用的序列化方式爲JdkSerializationRedisSerializer,因此咱們存入key前面會帶上一串東西,而StringRedisTemplate使用的是 StringRedisSerializer,序列化的方式不同,因此使用的時候key就不會出現一串字符串。

  解決方案:

  簡單瞭解緣由後,如今就來解決這個問題,解決問題的方法就是設置序列化方式

  

   這樣解決了上面的問題。問題倒不難,只是本身之前沒有遇到過,不知道這個方法是從網上直接複製的仍是本身寫的,只能說複製的時候不夠嚴謹,沒有考慮到項目的實際狀況,這個問題其實只要拿出一塊時間去看看代碼,查查資料就能解決,因此遇到問題的時候必定要找到緣由去解決問題,而不是把問題隱藏掉。

相關文章
相關標籤/搜索