在“Redis學習總結和相關資料”http://blog.csdn.net/fansunion/article/details/49278209
這篇文章中,對Redis做了總體的介紹,演示了Jedis和SpringDataRedis訪問Redis的相關例子。
對於基本的CRUD差不多夠了。
隨着項目中使用場景的增多,出現了存儲Java集合List的情況。
這個時候,一般的代碼很可能會報錯,比如“無法序列化”,“序列化失敗”之類的~
經過幾個小時的實踐探索,參考了在秒針工作的代碼以及最近的代碼,有2種可行方法。
需要說明的是,項目中用的是SpringDataRedis,但是Jedis代碼的思路也是一樣的。
項目中的Redis配置
- <bean id="businessRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
- <property name="connectionFactory" ref="businessConnectionFactory" />
- <!--如果不配置Serializer,那麼存儲的時候智能使用String,如果用User類型存儲,那麼會提示錯誤User can't cast
- to String!!! -->
- <property name="keySerializer">
- <bean
- class="org.springframework.data.redis.serializer.StringRedisSerializer" />
- </property>
- <property name="valueSerializer">
- <bean
- class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
- </property>
- </bean>
直接存儲java.util.List會提示“無法序列化”,“JdkSerializationRedisSerializer序列化失敗”類似的錯誤,
簡單的把java.util.List的元素實現Serialiable接口,是不行的。
也考慮了下,是不是和List元素的serialVersionUID有關係,最初用的是默認值1,改成系統生成的,也還是不行.
private static final long serialVersionUID = -2162380932844568332L;
方法1:把List轉換成JSON,存儲到Redis,取出來的時候,再把JSON轉換成List。
這種方法也很不錯,但是,當時咋就沒有想到呢。
序列化存儲
- List list = new ArrayList();
- String json=JSONObject.toJSONString(list);
- logger.info("save json="+json);
- defaultCache.add(key, json, CATCHE_TIME);
反序列化
- Object jsonInRedis = defaultCache.getValue(key);
- List<MatchContent> list = null;
- Object listInRedis = null;
- if(jsonInRedis != null){
- logger.info("get json="+jsonInRedis);
- listInRedis= JSONObject.parseArray(jsonInRedis.toString(), MatchContent.class);
- }
- if (listInRedis instanceof List) {
- list = (List) listInRedis;
- logger.debug("Find fund4Project in redis~ size=" + list.size());
- }
需要特別說明的是, JSONObject.parseArray可以把json格式的字符串,轉換成Java的List。
這個方法之前用的少,一直不熟悉,第2個參數是List元素的class。
自己寫的1個Demo。
- public static void main(String[] args) {
- List list = new ArrayList();
- list.add(new User());
- String json=JSONObject.toJSONString(list);
- System.out.println(json);
- List newList=JSONObject.parseArray(json, User.class);
- System.out.println(newList.size());
-
- }
方法2:把List轉換成二進制數組byte[],存儲到Redis,取出來的時候,再把byte[]轉成List。
序列化list->byte[]
- import hprose.io.HproseFormatter;
- java.io.ByteArrayOutputStream baos=HproseFormatter.serialize(list);
- 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序列化這個問題解決了,感覺方法很簡單。
還是那句經典的話“難題不會,會題不難”。
等把問題解決了,再難的問題,已經變得簡單了。沒解決的時候,急死你。
夥計,加油~