`
Josh_Persistence
  • 浏览: 1632032 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

Redis缓存Object,List对象 - Java 对象和List的序列化和反序列化

阅读更多

一、到目前为止(jedis-2.2.0.jar),在Jedis中其实并没有提供这样的API对对象,或者是List对象的直接缓存,即并没有如下类似的API

jedis.set(String key, Object value)

jedis.set(String key, List<M> values)

 

而更多的API是类似于jedis.set(String key, String value)或者jedis.set(String key, String ... value)

 

那如果我们想缓存对象,怎么办呢?

 

二、通过研究Jedis的API,我们发现其提供了这样的API

jedis.set(byte[], byte[]),

 

通过这个API,很显然我们能够实现

jedis.set(String key, Object value)

jedis.set(String key, List<M> values)

 

我们需要关注的就是在cache的时候将Object和List对象转换成字节数组并且需要提供将字节数组转换成对象返回。

 

三、考虑到扩展性,设计了3个类,抽象父类SerializeTranscoder, 子类ListTranscoder和ObjectsTranscoder 以及一个Unit test 类 用于模拟对象,list对象和字节数组的转换,即Serialize和de-searilize的过程。

 

1. SerializeTranscoder

 

 

package com.chuanliu.platform.activity.basic.util.serialize;

import java.io.Closeable;

import org.apache.log4j.Logger;


/**
 * @author Josh Wang(Sheng)
 *
 * @email  josh_wang23@hotmail.com
 */
public abstract class SerializeTranscoder {

	protected static Logger logger = Logger.getLogger(SerializeTranscoder.class);
	
	public abstract byte[] serialize(Object value);
	
	public abstract Object deserialize(byte[] in);
	
	public void close(Closeable closeable) {
		if (closeable != null) {
			try {
				closeable.close();
			} catch (Exception e) {
				 logger.info("Unable to close " + closeable, e); 
			}
		}
	}
}

 

 

2. ListTranscoder

 

package com.chuanliu.platform.activity.basic.util.serialize;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.chuanliu.platform.activity.basic.util.LoggerUtils;


/**
 * Case 1.
 * Jedis does not support cache the Object directly, the Objects needed to be 
 * serialized and de-serialized
 * 
 * Case 2.
 * coming very soon...
 * 
 * @author Josh Wang(Sheng)
 *
 * @email  josh_wang23@hotmail.com
 */
public class ListTranscoder<M extends Serializable> extends SerializeTranscoder {
	
	@SuppressWarnings("unchecked")
	public List<M> deserialize(byte[] in) {
		List<M> list = new ArrayList<>();
		ByteArrayInputStream bis = null;
		ObjectInputStream is = null;
		try {
			if (in != null) {
				bis = new ByteArrayInputStream(in);
				is = new ObjectInputStream(bis);
				while (bis.available() > 0) {
                                      // while(true) will throw EOFException
					M m = (M)is.readObject();
					if (m == null) {
						break;
					}
					
					list.add(m);
					
				}
				is.close();
				bis.close();
			}
		} catch (IOException e) {  
            LoggerUtils.error(logger, String.format("Caught IOException decoding %d bytes of data",  
                    in == null ? 0 : in.length) + e);  
        } catch (ClassNotFoundException e) {  
            LoggerUtils.error(logger, String.format("Caught CNFE decoding %d bytes of data",  
                    in == null ? 0 : in.length) + e);  
        }  finally {
			close(is);
			close(bis);
		}
		
		return  list;
	}
	

	@SuppressWarnings("unchecked")
	@Override
	public byte[] serialize(Object value) {
		if (value == null)
			throw new NullPointerException("Can't serialize null");
		
		List<M> values = (List<M>) value;
		
		byte[] results = null;
		ByteArrayOutputStream bos = null;
		ObjectOutputStream os = null;
		
		try {
			bos = new ByteArrayOutputStream();
			os = new ObjectOutputStream(bos);
			for (M m : values) {
				os.writeObject(m);
			}
			
			// os.writeObject(null);
			os.close();
			bos.close();
			results = bos.toByteArray();
		} catch (IOException e) {
			throw new IllegalArgumentException("Non-serializable object", e);
		} finally {
			close(os);
			close(bos);
		}
		
		return results;
	}

	
}

 

3. ObjectsTranscoder

package com.chuanliu.platform.activity.basic.util.serialize;



import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import com.chuanliu.platform.activity.basic.util.LoggerUtils;

/**
 * Case 1.
 * Jedis does not support cache the Object directly, the Objects needed to be 
 * serialized and de-serialized
 * 
 * Case 2.
 * coming very soon...
 * 
 * @author Josh Wang(Sheng)
 *
 * @email  josh_wang23@hotmail.com
 */
public class ObjectsTranscoder<M extends Serializable> extends SerializeTranscoder {

	
	@SuppressWarnings("unchecked")
	@Override
	public byte[] serialize(Object value) {
		if (value == null) {  
		    throw new NullPointerException("Can't serialize null");  
		}  
        byte[] result = null;  
        ByteArrayOutputStream bos = null;  
        ObjectOutputStream os = null;  
        try {  
            bos = new ByteArrayOutputStream();  
            os = new ObjectOutputStream(bos);
            M m = (M) value;
            os.writeObject(m);  
            os.close();  
            bos.close();  
            result = bos.toByteArray();  
        } catch (IOException e) {  
            throw new IllegalArgumentException("Non-serializable object", e);  
        } finally {  
            close(os);  
            close(bos);  
        }  
        return result;  
	}

	@SuppressWarnings("unchecked")
	@Override
	public M deserialize(byte[] in) {
		M result = null;  
		ByteArrayInputStream bis = null;  
		ObjectInputStream is = null;  
		try {  
	      if (in != null) {  
	          bis = new ByteArrayInputStream(in);  
	          is = new ObjectInputStream(bis);  
	          result = (M) is.readObject();  
	          is.close();  
	          bis.close();  
	      }  
		} catch (IOException e) {  
	      LoggerUtils.error(logger, String.format("Caught IOException decoding %d bytes of data",  
	              in == null ? 0 : in.length) + e);  
		} catch (ClassNotFoundException e) {  
	      LoggerUtils.error(logger, String.format("Caught CNFE decoding %d bytes of data",  
	              in == null ? 0 : in.length) + e);  
		} finally {  
	      close(is);  
	      close(bis);  
		}  
	  return result;  
	}
}

 

4. TestSerializerTranscoder

 

package com.chuanliu.platform.activity.basic.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.chuanliu.platform.activity.basic.util.serialize.ListTranscoder;
import com.chuanliu.platform.activity.basic.util.serialize.ObjectsTranscoder;

/**
 * @author Josh Wang(Sheng)
 *
 * @email  josh_wang23@hotmail.com
 */
public class TestSerializerTranscoder implements Serializable {
	
	private static final long serialVersionUID = -1941046831377985500L;

	public TestSerializerTranscoder() {
		
	}

	@Test
	public void testObject() {
		List<TestUser> lists = buildTestData();
		
		TestUser userA = lists.get(0);
		
		ObjectsTranscoder<TestUser> objTranscoder =  new ObjectsTranscoder<>();
		
		byte[] result1 = objTranscoder.serialize(userA);
		
		TestUser userA_userA = objTranscoder.deserialize(result1);
		
		System.out.println(userA_userA.getName() + "\t" + userA_userA.getAge());
	}
	
	@Test
	public void testList() {
		List<TestUser> lists = buildTestData();
		

		ListTranscoder<TestUser> listTranscoder = new ListTranscoder<>();
		
		byte[] result1 = listTranscoder.serialize(lists);
		
		List<TestUser> results = listTranscoder.deserialize(result1);
	
		for (TestUser user : results) {
			System.out.println(user.getName() + "\t" + user.getAge());
		}
		
	}
	
	private static List<TestUser> buildTestData() {
		TestSerializerTranscoder tst = new TestSerializerTranscoder();
		TestUser userA =  tst.new TestUser();
		userA.setName("lily"); 
        userA.setAge(25);
		
        
        TestUser userB = tst.new TestUser();  
        
        
        userB.setName("Josh Wang"); 
		userB.setAge(28);
        
        List<TestUser> list = new ArrayList<TestUser>();  
        list.add(userA);  
        list.add(userB);  
        
        return list;  
    }
	
	class TestUser implements Serializable {
		private static final long serialVersionUID = 1L;

			private String name;
			
			private int age;
			

			public String getName() {
				return name;
			}

			public void setName(String name) {
				this.name = name;
			}

			public int getAge() {
				return age;
			}

			public void setAge(int age) {
				this.age = age;
			}
			
		}
	
	
}

 

四、通过以上几步后,即可使用Jedis的API进行对象的缓存并将从缓存中返回的二进制数组转换成原始的对象或者是List对象了。

 

 

1
0
分享到:
评论
1 楼 wangkaick 2014-07-31  
那还不得慢死

相关推荐

    java开源包10

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包1

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包11

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包6

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包9

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包4

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包5

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包101

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包8

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java开源包3

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java开源包2

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    java开源包7

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    Java资源包01

    支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 ...

    免费分享 Java面试笔记 面试八股文 计算机网络基础

    Java基础:Java概念、基础语法、面向对象的理解、String类、Object类、序列化、泛型、注解与反射、JDK1.8新特性等;Java集合:List底层实现、Map底层实现等;Java并发编程:ThreadLocal、Java内存模型、锁、并发工具...

Global site tag (gtag.js) - Google Analytics