zoukankan      html  css  js  c++  java
  • 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序列化这个问题解决了,感觉方法很简单。
     还是那句经典的话“难题不会,会题不难”。
     等把问题解决了,再难的问题,已经变得简单了。没解决的时候,急死你。
     伙计,加油~

  • 相关阅读:
    设计模式(1)-行为类
    rocketmq(1)
    zookeeper(2)-curator
    Spring之HandlerInterceptor拦截器
    云之家如何获取登录用户信息?
    KDTable如何添加合计行?
    财务报表如何直接取数?
    DEP脚本
    Mybatis之关联查询及动态SQL
    Mybatis之XML、注解
  • 原文地址:https://www.cnblogs.com/qitian1/p/6462585.html
Copyright © 2011-2022 走看看