redis存取list<T>,及bug:Failed to serialize object of type: class com.google.common.collect.Lists$Revers

Redis存取List

实体类必须序列化,对于redis这种nosql数据库,实例化很重要,很多文章也都介绍了必须实例化,在配置redisTemplate时也会配置序列化规则:

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory" />
        <property name="KeySerializer">
            <bean
                class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
        </property>
        <property name="ValueSerializer">
            <bean
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
        </property>
        <property name="HashKeySerializer">
            <bean
                class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
        </property>
        <property name="HashValueSerializer">
            <bean
                class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
        </property>
    </bean>
redis存取List api
//存入List<T>,需要实现序列化
public <T> void putCache(JedisCluster jedisCluster,String key ,List<T> list,Integer liveSeconds){  
    	log.info("===========putCache===========key:"+key);
        try {  
        	if (null==liveSeconds ) {
                jedisCluster.set(SerializationUtils.serialize(cacheConfig.getPreFixKey(key).getBytes()) ,SerializationUtils.serialize(list));
            } else {
                jedisCluster.setex(SerializationUtils.serialize(cacheConfig.getPreFixKey(key).getBytes()), liveSeconds, SerializationUtils.serialize(list));
            }
        } catch (Exception e) {  
            log.error("Set key error : "+e);  
        }  
    }  
 //取List<T>需要实现反序列化
    public <T> List<T> getCache(JedisCluster jedisCluster,String key){ 
    	log.info("===========getCache===========key:"+key);
        byte[] in = jedisCluster.get(SerializationUtils.serialize(cacheConfig.getPreFixKey(key).getBytes()));
        if (null == in) {
			return null;
		}else{
			List<T> list = (List<T>) SerializationUtils.deserialize(in);  
			return list; 
		}
    }  
    //命名key的规则
    public String getPreFixKey(String key){
        return String.format("%s:%s",namespace,key);
    }
SerializationUtils类

不管是存入还是取出,都是通过字节流,这也是序列化的原因。

public abstract class SerializationUtils {

	/**
	 * Serialize the given object to a byte array.
	 * @param object the object to serialize
	 * @return an array of bytes representing the object in a portable fashion
	 */
	@Nullable
	public static byte[] serialize(@Nullable Object object) {
		if (object == null) {
			return null;
		}
		ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
		try {
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			oos.flush();
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
		}
		return baos.toByteArray();
	}

	/**
	 * Deserialize the byte array into an object.
	 * @param bytes a serialized object
	 * @return the result of deserializing the bytes
	 */
	@Nullable
	public static Object deserialize(@Nullable byte[] bytes) {
		if (bytes == null) {
			return null;
		}
		try {
			ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
			return ois.readObject();
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Failed to deserialize object", ex);
		}
		catch (ClassNotFoundException ex) {
			throw new IllegalStateException("Failed to deserialize object type", ex);
		}
	}

}

bug:Failed to serialize object of type: class com.google.common.collect.Lists$Revers

产生这个bug的原因是因为Lists.Revers没有实现序列化,所以存入redis的时候会报这个错误,当时遇到这个bug也查了好长时间,最后看这个Lists.Revers源码才发现这个问题。包括Lists.partition(),List.subList()等都没有实现序列化。

解决

将Lists.Revers、Lists.partition(),List.subList()等重新装入到已经实现序列化的list中去,问题解决

//Lists.Revers转list
List<User> list = new LinkedList<User>(); 
List<User> resutlListReverse = Lists.reverse(resutlList);
list.addAll(resutlListReverse);
//List.subList转list
List<User> subList = List.subList(0,10);
list.addAll(subList);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值