zoukankan      html  css  js  c++  java
  • 通用的ProtostuffSerializer for Java

    以前使用 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);
    try {
    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); }
    } finally {
    buffer.clear();
    } }
    /** * 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);
        }
    }
  • 相关阅读:
    POJ 2991(线段树)
    UVa_1592
    紫书 -- 大整数类
    在结构体中添加成员函数/C++
    双向队列
    用埃氏筛法生成质数表
    poj 3687(拓扑排序)
    它们其实都是“图”-- 最小生成树
    最小生成树(MST, Minimum Spanning Tree)
    他们其实都是“图”--最短路
  • 原文地址:https://www.cnblogs.com/lhfcws/p/6296725.html
Copyright © 2011-2022 走看看