1. 程式人生 > >Redis序列化儲存Java集合List等自定義型別

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

在“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序列化這個問題解決了,感覺方法很簡單。 還是那句經典的話“難題不會,會題不難”。 等把問題解決了,再難的問題,已經變得簡單了。沒解決的時候,急死你。 夥計,加油~