码迷,mamicode.com
首页 > 编程语言 > 详细

通用的ProtostuffSerializer for Java

时间:2017-01-18 15:05:24      阅读:956      评论:0      收藏:0      [点我收藏+]

标签: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

标签:time   sch   this   serialize   get   json   测试   merge   ignore   

原文地址:http://www.cnblogs.com/lhfcws/p/6296725.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!