Protostuff是基於Google protobuff技術的Java版本,直接使用原生的protobuff是需要數據結構的預編譯過程,需要編寫.proto格式的配置文件,再通過protobuff提供的工具翻譯成目標語言代碼,而Protostuff動態支持了protobuff的預編譯的過程,可以直接使用普通java POJO進行序列化,簡化編碼。
經過實測序列化性能相對原生protpbuff沒有影響。
由於Protostuff只支持Java實現,不過並未對序列化格式有做任何修改,所以Protostuff和protobuff可以共同使用。
import io.protostuff.LinkedBuffer; import io.protostuff.ProtobufIOUtil; import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p> * 使用Protostuff進行序列化/反序列化 * </p> * * @author * @version V1.0 * @modify by user: {修改人} 2015年6月19日 * @modify by reason:{方法名}:{原因} */ public class ProtostuffUtil { private static final Logger LOG = LoggerFactory.getLogger(ProtostuffUtil.class); /** * * <p> * 序列化類型 * </p> * * @author * @version V1.0 * @modificationHistory=========================邏輯或功能性重大變更記錄 * @modify by user: $author$ $date$ * @modify by reason: {方法名}:{原因} */ public static enum SerializeType { protobuf, protoStuff; } /** * 序列化(默認采用ProtoStuff方式) * * @author * @param t * @return */ public static <T> byte[] serialize(T t) { return serialize(t, SerializeType.protoStuff); } /** * 序列化 * * @author * @param t * @param type * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T> byte[] serialize(T t, SerializeType type) { if (t == null) { return null; } Schema schema = RuntimeSchema.getSchema(t.getClass()); LinkedBuffer buffer = LinkedBuffer.allocate(1024); byte[] data; switch (type) { case protoStuff: data = ProtostuffIOUtil.toByteArray(t, schema, buffer); break; case protobuf: data = ProtobufIOUtil.toByteArray(t, schema, buffer); break; default: String errMsg = "Can not serialize by other type"; LOG.error(errMsg); throw new RuntimeException(errMsg); } return data; } /** * 反序列化,傳入對象實例 * * @author * @param t * @param bs * @param type */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static <T> void deserialize(T t, byte[] bs,SerializeType type) { Schema schema = RuntimeSchema.getSchema(t.getClass()); switch (type) { case protoStuff: ProtostuffIOUtil.mergeFrom(bs, t, schema); break; case protobuf: ProtobufIOUtil.mergeFrom(bs, t, schema); break; default: String errMsg = "Can not deserialize by other type"; LOG.error(errMsg); throw new RuntimeException(errMsg); } } /** * 反序列化,傳入對象實例(默認使用ProtoStuff方式) * * @author zhuchao 2015年6月29日 下午6:20:16 * @param clazz * @param t * @param bs */ public static <T> void deserialize(T t, byte[] bs) { deserialize(t, bs, SerializeType.protoStuff); } /** * 反序列化(反序列化類必須實現無參構造函數) * * @author * @param bs * @return */ public static <T> T deserialize(Class<T> clazz, byte[] bs,SerializeType type) { T t = null; try { t = (T) clazz.newInstance(); deserialize(t, bs,type); } catch (Exception e) { LOG.error("反序列化異常", e); } return t; } /** * 反序列化(反序列化類必須實現無參構造函數)(默認使用ProtoStuff方式) * * @author * @param bs * @return */ public static <T> T deserialize(Class<T> clazz, byte[] bs) { return deserialize(clazz, bs, SerializeType.protoStuff); } }
