通用的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);
}
}
通用的ProtostuffSerializer for Java的更多相关文章
- 通用且常用的Java正则匹配工具,用以检查邮箱名、电话号码、用户密码、邮政编码等合法性
一个通用且常用的Java正则匹配工具,用以检查邮箱名.电话号码.用户密码.邮政编码等合法性. import java.util.regex.Matcher; import java.util.rege ...
- AES加密解密通用版Object-C / C# / JAVA
1.无向量 128位 /// <summary> /// AES加密(无向量) /// </summary> /// <param name="plainByt ...
- 编写通用shell脚本启动java项目,适用于多数服务,只需修改服务名即可
文件名:service-user.sh 文件内容: ##shell脚本的头文件必须有#!/bin/sh ##再次配置java环境变量以防报其他错误## java env#jdk安装目录export J ...
- 通用RSA加密 - PHP+Java+Javascript加密解密
php端生成 公钥私钥 1.openssl genrsa -out rsa_private_key.pem 1024 私钥 2.openssl rsa -in rsa_private_key.p ...
- Java简单实现AOP,Java通用异常拦截,Java与Lamada
直接看代码不废话.不懂Lamada直接百度... package test; /** * QQ:1448376744 * @author 花间岛 * */ //控制器 public class Con ...
- Java通用oracle和mysql数据库连接
Java中oracle数据库连接写一个通用类UBUtil(){} import java.io.InputStream; import java.sql.*; import java.util.Pro ...
- Effective Java:对于全部对象都通用的方法
前言: 读这本书第1条规则的时候就感觉到这是一本非常好的书.可以把我们的Java功底提升一个档次,我还是比較推荐的.这里我主要就关于覆盖equals.hashCode和toString方法来做一个笔记 ...
- 浅析Java 泛型
泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...
- Java JNI 编程进阶 实例+c++数据类型与jni数据类型转换
原文:http://www.iteye.com/topic/295776 JNI一直以来都很少去关注,但却是我心中的一个结,最近这几天刚好手头有点时间,因此抽空看了一下这方面的东西,整理了一份文档,J ...
随机推荐
- git报错处理
今天又遇到了这个问题,记录一下. 报错 原因及解决办法: 本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http ...
- RPC远程过程调用实例
什么是RPC RPC 的全称是 Remote Procedure Call 是一种进程间通信方式.它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程 ...
- 使用Eclipse绑定Tomcat并发布应用
l 步骤1:获得服务器运行环境配置,Window/Preferences/Server/Runtime Environmen l步骤2:添加服务器 l步骤3:选择服务器在硬盘的地址,然后所有的都是确定 ...
- 【转】利用 selenium 的 webdrive 驱动 headless chrome
1.参考 使用 headless chrome进行测试 2.概念 Headless模式解决了什么问题: 自动化工具例如 selenium 利用有头浏览器进行测试,面临效率和稳定性的影响,所以出现了 H ...
- 一起学Hadoop——使用IDEA编写第一个MapReduce程序(Java和Python)
上一篇我们学习了MapReduce的原理,今天我们使用代码来加深对MapReduce原理的理解. wordcount是Hadoop入门的经典例子,我们也不能免俗,也使用这个例子作为学习Hadoop的第 ...
- 【转】PropertyGrid控件中的多级显示
运行效果: 解决方案: MainForm.cs public partial class MainForm : Form { public MainForm() { InitializeCompone ...
- IIS 无法显示网页 目前访问网站的用户过多
最近把一个服务部署到XP系统的IIS上,供其他程序调用,在访问了几个页面后,会出现“无法显示网页 目前访问网站的用户过多”的提示. 网上找了,果然有解决方法: 1.打开IIS,在网站上右键,选择“属性 ...
- BZOJ4811 [Ynoi2017]由乃的OJ 树链剖分
原文链接http://www.cnblogs.com/zhouzhendong/p/8085286.html 题目传送门 - BZOJ4811 题意概括 是BZOJ3668长在树上并加上修改和区间询问 ...
- ELK安装(ubuntu)
一.安装jdk8 经过我测试logstash5.x不支持java10和11,所以安装java8 加入LinuxUprising Java PPA sudo add-apt-repository ppa ...
- P1120 小木棍 [数据加强版] 回溯法 终极剪枝
题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度 ...