Redis序列化存儲Java集合List等自定義類型

在“Redis學習總結和相關資料”http://blog.csdn.net/fansunion/article/details/49278209
這篇文章中,對Redis做了總體的介紹,演示了Jedis和SpringDataRedis訪問Redis的相關例子。
對於基本的CRUD差不多夠了。

隨着項目中使用場景的增多,出現了存儲Java集合List的情況。
這個時候,一般的代碼很可能會報錯,比如“無法序列化”,“序列化失敗”之類的~

經過幾個小時的實踐探索,參考了在秒針工作的代碼以及最近的代碼,有2種可行方法。

需要說明的是,項目中用的是SpringDataRedis,但是Jedis代碼的思路也是一樣的。


項目中的Redis配置
  1. <bean id="businessRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
  2.         <property name="connectionFactory" ref="businessConnectionFactory" />  
  3.         <!--如果不配置Serializer,那麼存儲的時候智能使用String,如果用User類型存儲,那麼會提示錯誤User can't cast   
  4.             to String!!! -->  
  5.         <property name="keySerializer">  
  6.             <bean  
  7.                 class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  8.         </property>  
  9.         <property name="valueSerializer">  
  10.             <bean  
  11.                 class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />  
  12.         </property>  
  13.     </bean>  

直接存儲java.util.List會提示“無法序列化”,“JdkSerializationRedisSerializer序列化失敗”類似的錯誤,
簡單的把java.util.List的元素實現Serialiable接口,是不行的。
也考慮了下,是不是和List元素的serialVersionUID有關係,最初用的是默認值1,改成系統生成的,也還是不行.
private static final long serialVersionUID = -2162380932844568332L;
方法1:把List轉換成JSON,存儲到Redis,取出來的時候,再把JSON轉換成List。
這種方法也很不錯,但是,當時咋就沒有想到呢。
序列化存儲
 
  1. List list = new ArrayList();  
  2.   String json=JSONObject.toJSONString(list);  
  3.   logger.info("save json="+json);  
  4.   defaultCache.add(key, json, CATCHE_TIME);  

 
反序列化
     
  1. Object jsonInRedis = defaultCache.getValue(key);  
  2. List<MatchContent> list = null;  
  3. Object listInRedis = null;  
  4. if(jsonInRedis != null){  
  5.     logger.info("get json="+jsonInRedis);  
  6.     listInRedis= JSONObject.parseArray(jsonInRedis.toString(), MatchContent.class);  
  7. }  
  8. if (listInRedis instanceof List) {  
  9.     list = (List) listInRedis;  
  10.     logger.debug("Find fund4Project in redis~ size=" + list.size());  
  11. }  

需要特別說明的是, JSONObject.parseArray可以把json格式的字符串,轉換成Java的List。
這個方法之前用的少,一直不熟悉,第2個參數是List元素的class。
  自己寫的1個Demo。
  1. public static void main(String[] args) {  
  2.         List list = new ArrayList();  
  3.         list.add(new User());  
  4.         String json=JSONObject.toJSONString(list);  
  5.         System.out.println(json);  
  6.         List newList=JSONObject.parseArray(json, User.class);  
  7.         System.out.println(newList.size());  
  8.           
  9.     }  

方法2:把List轉換成二進制數組byte[],存儲到Redis,取出來的時候,再把byte[]轉成List。
序列化list->byte[]
  1. import hprose.io.HproseFormatter;  
  2. java.io.ByteArrayOutputStream baos=HproseFormatter.serialize(list);  
  3.             byte[] bytes=baos.toByteArray();  

二進制反序列化byte[]->list
 listInRedis = HproseFormatter.unserialize((byte[] )bytesInRedis);
 
 項目中用的是源代碼,從秒針代碼中copy出來的庫。
 
 上述2種方法,使用JSON序列化存儲,感覺更簡單一些。
 但是據說HproseFormatter這個庫,很牛逼,按照官網的說法。

 Hprose(High Performance Remote Object Service Engine)
是一款先進的輕量級、跨語言、跨平臺、無侵入式、高性能動態遠程對象調用引擎庫。它不僅簡單易用,而且功能強大。
你無需專門學習,只需看上幾眼,就能用它輕鬆構建分佈式應用系統。

 網上找到了hprose的資料,不出意外的話,可以用下面這個的。
 hprose/hprose-java
 https://github.com/hprose/hprose-java/tree/master/src
  
  Map等其它類型的存儲,和List類似~
  
  把Redis序列化這個問題解決了,感覺方法很簡單。
 還是那句經典的話“難題不會,會題不難”。
 等把問題解決了,再難的問題,已經變得簡單了。沒解決的時候,急死你。
 夥計,加油~

發佈了23 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章