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);
        }
    }
  • 相关阅读:
    LVS基于DR模式负载均衡的配置
    Linux源码安装mysql 5.6.12 (cmake编译)
    HOSt ip is not allowed to connect to this MySql server
    zoj 3229 Shoot the Bullet(无源汇上下界最大流)
    hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割
    poj 2391 Ombrophobic Bovines(最大流+floyd+二分)
    URAL 1430 Crime and Punishment
    hdu 2048 神、上帝以及老天爷(错排)
    hdu 3367 Pseudoforest(最大生成树)
    FOJ 1683 纪念SlingShot(矩阵快速幂)
  • 原文地址:https://www.cnblogs.com/lhfcws/p/6296725.html
Copyright © 2011-2022 走看看