package com.book.core.test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.book.core.model.Type;
import com.book.core.serializable.SerializationUtil;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtobufIOUtil;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;

/**
 * ProtoStuff测试
 * @author liweihan
 *
 */
public class TestProtoStuff {
	public static void main(String[] args) throws Exception {
		
		/**
		 * *********** 测试1 : 原始的序列化对象 ************
		 */
		//序列化
		System.out.println(" ========= 序列化开始:" );
		Schema<Type> schema = RuntimeSchema.getSchema(Type.class);
		Type type = new Type();
		type.setCityId(1);
		type.setPrice(new BigDecimal(100));
		type.setTypeName("韩超");
		
		LinkedBuffer buffer = LinkedBuffer.allocate(1024);
		byte[] data = ProtobufIOUtil.toByteArray(type, schema, buffer);
		System.out.println("序列化后的大小:" + data.length + " 字节 !");
		
		//反序列化
		System.out.println(" ========= 反序列化开始:" );
		Type type2 = new Type();
		ProtobufIOUtil.mergeFrom(data, type2, schema);
		System.out.println(" ====== 反序列化后的结果为:cityId:" + type2.getCityId() 
				+ " ,typeName:" + type2.getTypeName() 
				+ " , price:" + type2.getPrice());
		
		
		/**
		 * ************ 测试2 :单独序列化集合 **************
		 */
		Type t1 = new Type();
		t1.setId(1);
		t1.setCityId(1);
		t1.setPrice(new BigDecimal(1));
		t1.setTypeName("TestHan");
		
		List<Type> list1 = new ArrayList<Type>();
		list1.add(t1);
		list1.add(type);
		
		System.out.println(" *********** 序列化开始: ");
		List<byte[]> result = serializeProtoStuffTypeList(list1);
		System.out.println("序列化后集合的大小:" + result.size());
		
		System.out.println(" *********** 反序列化开始: ");
		List<Type> l = deserializeProtoStuffToTypeList(result);
		System.out.println(" 反序列化后的集合大小为:" + l.size() + " , name1:" + l.get(0).getTypeName());
		
		/*********** 测试 3 *****************/
		Type type1 = new Type();
		type1.setCityId(2);
		type1.setPrice(new BigDecimal(100));
		type1.setTypeName("太");
		
		System.out.println(" ------ 序列化开始:");
		byte[] type1Ser = SerializationUtil.object2Bytes_obj(type1);
		System.out.println(" ------- 序列化后的大小:" + type1Ser.length);
		
		System.out.println(" ------ 反序列化开始:");
		Type type1Result = (Type)SerializationUtil.bytes2Object(type1Ser);
		System.out.println(" ====== 反序列化后的结果为:cityId:" + type1Result.getCityId() 
				+ " ,typeName:" + type1Result.getTypeName() 
				+ " , price:" + type1Result.getPrice());
		
	
		/******************** 测试4 :序列化集合 **********************/
		Type t2 = new Type();
		t2.setId(2);
		t2.setCityId(2);
		t2.setPrice(new BigDecimal(23));
		t2.setTypeName("ZHANG");
		
		ArrayList<Type> list2 = new ArrayList<Type>();
		list2.add(t2);
		list2.add(t1);
		
		System.out.println(" ++++++++++++++   序列化开始: ");
		byte[] result2 =  SerializationUtil.object2Bytes(list2);
		System.out.println(" 序列化的大小: " + result2.length);
		
		System.out.println(" ++++++++++++++   序列化结束: ");
		List<Type> listResult = (List<Type>)SerializationUtil.bytes2Object(result2);
		for (Type t: listResult) {
			System.out.println(t.getTypeName());
		}
	}
	
	/**
	 * 序列化Type的List集合
	 * @param tList
	 * @return
	 */
	public static List<byte[]> serializeProtoStuffTypeList(List<Type> tList) {
		if (tList == null || tList.size() <= 0) {
			return null;
		}
		
		List<byte[]> bytes = new ArrayList<byte[]>();
		Schema<Type> schema = RuntimeSchema.getSchema(Type.class);
		LinkedBuffer buffer = LinkedBuffer.allocate(1024);
		byte[] protostuff = null;
		for(Type t: tList) {
			try {
				protostuff = ProtostuffIOUtil.toByteArray(t, schema, buffer);
				bytes.add(protostuff);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				buffer.clear();
			}
		}
		
		return bytes;
	}
	
	/**
	 * 反序列化Type的List集合
	 * @param bytesList
	 * @return
	 */
	public static List<Type> deserializeProtoStuffToTypeList(List<byte[]> bytesList) {
		if (bytesList == null || bytesList.size() <= 0) {
			return null;
		}
		
		Schema<Type> schema = RuntimeSchema.getSchema(Type.class);
		List<Type> list = new ArrayList<Type>();
		for (byte[] bs : bytesList) {
			Type type = new Type();
			ProtostuffIOUtil.mergeFrom(bs, type, schema);
			list.add(type);
		}
		return list;
	}
}
package com.book.core.serializable;

import java.io.Serializable;

public class SerializationUtil {
	
    public static ProtostuffSerializer protostuffSerializer;

	static {
		protostuffSerializer = new ProtostuffSerializer();
	}


	public static byte[] object2Bytes(Serializable obj) throws Exception {
		if (obj == null) {
			return null;
		}

		return protostuffSerializer.serialize(obj);

/*		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(obj);
		bo.close();
		oo.close();
		return bo.toByteArray();*/
	}
	
	/**
	 * 序列化【序列化对象不需要实现Serializable】
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public static byte[] object2Bytes_obj(Object obj) throws Exception {
		if (obj == null) {
			return null;
		}
		
		return protostuffSerializer.serialize(obj);
	}

	public static byte[][] objects2Bytes(Serializable[] obj) throws Exception {
		if (obj == null) {
			return null;
		}
		byte[][] many = new byte[obj.length][];
		for(int i=0;i<obj.length;i++){
			many[i] = object2Bytes(obj[i]);
		}
		return many;
	}


	public static Object bytes2Object(byte[] objBytes) throws Exception {
		if (objBytes == null || objBytes.length == 0) {
			return null;
		}
		Object obj = protostuffSerializer.deserialize(objBytes);
		return obj;

		/*ByteArrayInputStream bi = new ByteArrayInputStream(objBytes);
		ObjectInputStream oi = new ObjectInputStream(bi);
		obj = oi.readObject();
		bi.close();
		oi.close();
		return obj;*/
	}

}
package com.book.core.serializable;


import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;

import java.util.concurrent.ConcurrentHashMap;

public class ProtostuffSerializer {
	
    private static ConcurrentHashMap<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();

    public <T> byte[] serialize(final T source) {
        VO<T> vo = new VO<T>(source);

        final LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            final Schema<VO> schema = getSchema(VO.class);
            return serializeInternal(vo, schema, buffer);
        } catch (final Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            buffer.clear();
        }
    }

    public <T> T deserialize(final byte[] bytes) {
        try {
            Schema<VO> schema = getSchema(VO.class);
            VO vo = deserializeInternal(bytes, schema.newMessage(), schema);
            if (vo != null && vo.getValue() != null) {
                return (T) vo.getValue();
            }
        } catch (final Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        return null;
    }

    private <T> byte[] serializeInternal(final T source, final Schema<T> schema, final LinkedBuffer buffer) {
        return ProtostuffIOUtil.toByteArray(source, schema, buffer);
    }

    private <T> T deserializeInternal(final byte[] bytes, final T result, final Schema<T> schema) {
        ProtostuffIOUtil.mergeFrom(bytes, result, schema);
        return result;
    }

    private static <T> Schema<T> getSchema(Class<T> clazz) {
        @SuppressWarnings("unchecked")
        Schema<T> schema = (Schema<T>) cachedSchema.get(clazz);
        if (schema == null) {
            schema = RuntimeSchema.createFrom(clazz);
            cachedSchema.put(clazz, schema);
        }
        return schema;
    }

}
package com.book.core.serializable;

import java.io.Serializable;

/**
 * Created by yijunzhang on 14-4-2.
 */
public class VO<T> implements Serializable {

    private T value;

    public VO(T value) {
        this.value = value;
    }

    public VO() {
    }

    public T getValue() {
        return value;
    }

    @Override
    public String toString() {
        return "VO{" +
                "value=" + value +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof VO)) return false;
        VO vo = (VO) o;
        if (value != null ? !value.equals(vo.value) : vo.value != null) return false;
        return true;
    }

    @Override
    public int hashCode() {
        return value != null ? value.hashCode() : 0;
    }
}
package com.book.core.model;

import java.math.BigDecimal;

public class Type {
    private Integer id;

    private String typeName;

    private BigDecimal price;

    private Integer cityId;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName == null ? null : typeName.trim();
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Integer getCityId() {
        return cityId;
    }

    public void setCityId(Integer cityId) {
        this.cityId = cityId;
    }
}
			<dependency>
			  <groupId>com.dyuproject.protostuff</groupId>
			  <artifactId>protostuff-core</artifactId>
			  <version>${protostuff.version}</version>
			</dependency>
			<dependency>
			  <groupId>com.dyuproject.protostuff</groupId>
			  <artifactId>protostuff-runtime</artifactId>
			  <version>${protostuff.version}</version>
			</dependency>
			<dependency>
			  <groupId>com.dyuproject.protostuff</groupId>
			  <artifactId>protostuff-api</artifactId>
			  <version>${protostuff.version}</version>
			</dependency>
			<dependency>
			  <groupId>com.dyuproject.protostuff</groupId>
			  <artifactId>protostuff-collectionschema</artifactId>
			  <version>${protostuff.version}</version>
			</dependency>
<protostuff.version>1.0.8</protostuff.version>

序列化的几种方式

http://my-corner.iteye.com/blog/1776512



Java序列化简单了解

http://hanchaohan.blog.51cto.com/2996417/922470



jprotobuf的简单了解

https://github.com/jhunters/jprotobuf



java序列化/反序列化之xstream、protobuf、protostuff 的比较与使用例子

http://www.cnblogs.com/xiaoMzjm/p/4555209.html



注意事项:String对象要不要序列化的问题,个人建议不要。

假如,我们调用一个接口:http://api.tv.xxxx.com/v4/video/info/3784655.json?site=1&api_key=695fe827ffeb7d74260a813025970bd5&plat=17&partner=1&sver=3.5&poid=1&aid=0

返回一个JSON类型的字符串。


我们需要把字符串存入redis缓存中,我们有3中方式缓存

1:直接存储String对象

2:序列化String对象后,存入redis

3:转为JSON对象,序列化JSON对象后,存入redis


下面我们打印一下三种方式,所占用的空间大小,我们发现序列化后,对象大小都普通增大了。

这样,会多占用我们缓存的空间。

如果是json string类型的 可以不序列化 redis的客户端会做getbytes做字节流的转换 其实就是做string的序列化

wKioL1m1_nbSZV5NAAEfjxBdShA472.jpg

wKiom1m1_pyCUX3fAACiyvpqmlI303.jpg