標籤:time sch this serialize get json 測試 merge ignore
以前使用 protobuf或protostuff的時候覺得很麻煩,每個類都要單獨定製,於是封裝了一個類。
同事測試過,效能和壓縮率都很好,尤其是相比json的序列化。
需注意:只支援Pojo類(即需要有get/set方法)、對一個新的class第一次調用初始化會有一兩百毫秒的register時間,之後就很快了。
import io.protostuff.LinkedBuffer;import io.protostuff.ProtostuffIOUtil;import io.protostuff.Schema;import io.protostuff.runtime.RuntimeSchema;import java.io.Serializable;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/** * Protostuff serializer tool, for POJO serialization. * Protostuff is much more efficient than json, even faster than Protobuf and Avro, but the serialized string is human-unreadable. * Not support Array or Generic-type, please wrap these special objects via a POJO with empty constructors. * * @author lhfcws * @since 2016-03-16 */public class ProtostuffSerializer implements Serializable { static Map<Class, Schema> schemaCache = new ConcurrentHashMap<>(); /** * common protostuff serialize, object need a empty constructor * Be careful to convert result byte[] to String, use new String(bytes, StandardCharsets.UTF_16LE). * * @param obj * @param <T> * @return */ public static <T> byte[] serializeObject(T obj) { Class<T> klass = (Class<T>) obj.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(4096); if (schemaCache.containsKey(klass)) { return ProtostuffIOUtil.toByteArray(obj, schemaCache.get(klass), buffer); } else { schemaCache.put(klass, RuntimeSchema.getSchema(klass)); return ProtostuffIOUtil.toByteArray(obj, schemaCache.get(klass), buffer); } } /** * common protostuff unserialize * * @param bs * @param klass * @param <T> * @return */ public static <T> T deserialize(byte[] bs, Class<T> klass) { if (schemaCache.containsKey(klass)) { Schema<T> schema = schemaCache.get(klass); T msg = schema.newMessage(); ProtostuffIOUtil.mergeFrom(bs, msg, schema); return msg; } else { Schema<T> schema = RuntimeSchema.getSchema(klass); T msg = schema.newMessage(); schemaCache.put(klass, schema); ProtostuffIOUtil.mergeFrom(bs, msg, schema); return msg; } }}
使用demo:
// 如果是Pojo類直接調用就行了,非Pojo類參考如下:(假設已有一個StrParams model類) public static class StrParamsPojo { private StrParams p; public StrParamsPojo() { } public StrParamsPojo(StrParams p) { this.p = p; } public StrParams getP() { return p; } public void setP(StrParams p) { this.p = p; } } public void serialize() throws IOException { StrParams p = new StrParams(); StrParamsPojo pojo = new StrParamsPojo(p); byte[] bs = ProtostuffSerializer.serializeObject(pojo); } public void deserialize(byte[] bs) throws IOException { StrParamsPojo pojo = ProtostuffSerializer.deserialize(bs, StrParamsPojo.class); StrParams p = pojo.getP(); }
附送一個FastJsonSerializer:
import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.serializer.SerializerFeature;import java.lang.reflect.Type;/** * FastJson is faster than Gson. * But DO remember your objects has get/set for the fields you want to serialze. * @author lhfcws */public class FastJsonSerializer { /** * 把給定的對象序列化成json字串 * @param obj 給定的對象 * @return 對象序列化後的json字串 */ public static <T> String serialize(T obj) { return JSON.toJSONString(obj, SerializerFeature.IgnoreNonFieldGetter, SerializerFeature.SkipTransientField, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.BrowserCompatible ); } public static <T> String serializePretty(T obj) { return JSON.toJSONString(obj, SerializerFeature.IgnoreNonFieldGetter, SerializerFeature.SkipTransientField, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.BrowserCompatible, SerializerFeature.PrettyFormat ); } /** * 根據類名把json字串還原序列化成實體類對象 * @param json 待還原序列化的json字串 * @param klass 還原序列化的實體類 * @return 還原序列化後的對象 */ public static <T> T deserialize(String json, Class<T> klass) { return JSON.parseObject(json, klass); } /** * 把Json字串還原序列化成實現了Type介面的實體類對象 * @param json 待還原序列化的json字串 * @param type 泛型型別 * @return 還原序列化後的對象 */ public static <T> T deserialize(String json, Type type) { return JSON.parseObject(json, type); }}
通用的ProtostuffSerializer for Java