文档章节

MessagePack Java的使用

cloud-coder
 cloud-coder
发布于 2016/11/16 17:33
字数 1092
阅读 196
收藏 3

MessagePack是一个高效的二进制序列化格式。它让你像JSON一样可以在各种语言之间交换数据。但是它比JSON更快、更小。

使用Maven添加MessagePack的依赖:

<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>${msgpack.version}</version>
</dependency>

在本篇文章中使用的版本为

<msgpack.version>0.6.6</msgpack.version>

首先创建一个实体类UserInfo(注意对类加上Message注解)

import org.msgpack.annotation.Message;


@Message
public class UserInfo {


private String userName;
private int userID;

public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}

public UserInfo buildUserName(String userName){
this.userName = userName;
return this;
}

public UserInfo buildUserID(int userID){
this.userID = userID;
return this;
}

@Override
public String toString() {
return "UserInfo [userName=" + userName + ", userID=" + userID + "]";
}
}

看下如何进行序列化和反序列化

public class SerializablePerform {


public static void main(String[] args) throws Exception {
UserInfo userInfo = new UserInfo();
userInfo.buildUserID(250).buildUserName("saolangjian");
MessagePack messagePack = new MessagePack();
//序列化
byte[] bs = messagePack.write(userInfo);
System.out.println("byte array's length is : "+bs.length);
//反序列化
UserInfo serializableUserinfo = messagePack.read(bs, UserInfo.class);
System.out.println(serializableUserinfo);

}

}

如果想按顺序地序列化多个对象,可以使用Packer和Unpacker对象,这是因为每次的MessagePack.write(Object)和read(byte[])方法调用都会创建Packer和Unpacker对象,可以使用createPacker(OutputStream)和createUnpacker(InputStream)创建Packer对象和Unpacker对象

@Test
public void testMultiObjects() throws Exception {
UserInfo u1 = new UserInfo();
UserInfo u2 = new UserInfo();
UserInfo u3 = new UserInfo();
u1.buildUserID(250).buildUserName("saolangjian");
u2.buildUserID(25).buildUserName("shengun");
u3.buildUserID(13).buildUserName("chuichui");
MessagePack messagePack = new MessagePack();
//序列化
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Packer packer = messagePack.createPacker(outputStream);
packer.write(u1);
packer.write(u2);
packer.write(u3);
byte[] bs = outputStream.toByteArray();
System.out.println("byte array's length is : "+bs.length);
//反序列化
ByteArrayInputStream inputStream = new ByteArrayInputStream(bs);
Unpacker unpacker = messagePack.createUnpacker(inputStream);
UserInfo su1 = unpacker.read(UserInfo.class);
System.out.println(su1);
UserInfo su2 = unpacker.read(UserInfo.class);
System.out.println(su2);
UserInfo su3 = unpacker.read(UserInfo.class);
System.out.println(su3);
}

Packer/Unpacker类允许序列化/反序列化多种类型的值,可以序列化/反序列化基本类型,基本类型的包装类,String对象,byte[]对象和ByteBuffer对象等。

@Test
public void testVariousType() throws Exception{
MessagePack messagePack = new MessagePack();

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Packer packer = messagePack.createPacker(outputStream);
//序列化基本类型
packer.write(true);
packer.write(10);
packer.write(10.1);
//序列化基本类型的包装类
packer.write(Boolean.TRUE);
packer.write(new Integer(10));
packer.write(new Double(10.1));
//序列化多种类型的数组
packer.write(new int[]{1,2,3,4});
packer.write(new Double[]{10.1,250.25});
packer.write(new String[]{"slj","cz","sg"});
packer.write(new byte[]{1,3,1});
//序列化其他引用类型
packer.write("saolangjian");
packer.write(ByteBuffer.wrap(new byte[]{1,3,1}));
packer.write(BigInteger.ONE);
byte[] bs = outputStream.toByteArray();

//反序列化
ByteArrayInputStream inputStream = new ByteArrayInputStream(bs);
Unpacker unpacker = messagePack.createUnpacker(inputStream);

boolean b = unpacker.readBoolean();
System.out.println(b);
int i = unpacker.readInt();
System.out.println(i);
double d = unpacker.readDouble();
System.out.println(d);
Boolean boolean1 = unpacker.read(Boolean.class);
System.out.println(boolean1);
Integer integer = unpacker.read(Integer.class);
System.out.println(integer);
Double double1 = unpacker.read(Double.class);
System.out.println(double1);
int[] js = unpacker.read(int[].class);
System.out.println(js.length);
Double[] doubles = unpacker.read(Double[].class);
System.out.println(doubles.length);
String[] strings = unpacker.read(String[].class);
System.out.println(strings.length);
byte[] cs = unpacker.read(byte[].class);
System.out.println(cs.length);
String text = unpacker.read(String.class);
System.out.println(text);
ByteBuffer buffer = unpacker.read(ByteBuffer.class);
byte[] newByte = new byte[buffer.remaining()];
System.out.println("remaining : "+buffer.remaining());
buffer.get(newByte);
System.out.println(new String(newByte));
BigInteger bigInteger = unpacker.read(BigInteger.class);
System.out.println(bigInteger);
}

可以使用Template来序列化容器比如List和Map,当序列化一个List对象,其中的元素是Integer类型时,创建Template的方法是:

Template<List<Integer>> integerTemplate = Templates.tList(Templates.TInteger);

其中tList是Templates的静态方法,TInteger是Templates的静态字段

@Test
public void testContainer () throws Exception{
MessagePack messagePack = new MessagePack();

Template<List<String>> listTemplate = Templates.tList(Templates.TString);
Template<Map<String, String>> mapTemplate = Templates.tMap(Templates.TString, Templates.TString);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Packer packer = messagePack.createPacker(outputStream);
List<String> list = new ArrayList<String>();
list.add("saolangjian");
list.add("axiba");
list.add("woX");
packer.write(list);

Map<String, String> map = new HashMap<String,String>();
map.put("slj", "cz");
map.put("sg", "cc");
packer.write(map);

byte[] bs = outputStream.toByteArray();

ByteArrayInputStream inputStream = new ByteArrayInputStream(bs);
Unpacker unpacker = messagePack.createUnpacker(inputStream);
List<String> seList = unpacker.read(listTemplate);
System.out.println(seList);
Map<String, String> seMap = unpacker.read(mapTemplate);
System.out.println(seMap);
}

有些情况下,我们使用的实体类是外部类库中引用的,这时我们不能将@Message注解添加到类声明上,此时就有另一种方法进行操作,使用MessagePack.register方法

实体类的定义如下:

public class Account {

private double balance;
private String details;

public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}

@Override
public String toString() {
return "Account [balance=" + balance + ", details=" + details + "]";
}

}

序列化和反序列化的方法如下:

@Test
public void testRegister() throws Exception{
Account account = new Account();
account.setBalance(10.01);
account.setDetails("xxoo");
MessagePack messagePack = new MessagePack();
messagePack.register(Account.class);
byte[] bs = messagePack.write(account);
System.out.println(bs.length);
Account seAccount = messagePack.read(bs,Account.class);
System.out.println(seAccount);
}

为了保证序列化向前兼容,使用@Optional注解对新增加的字段,当反序列化旧版本的数据时,加入@Optional注解的字段就会被忽略

MessagePack提供了动态类型的功能,通过接口Value来实现动态类型,首先将字节数组序列化为Value类型的对象,然后用converter转化为本身的类型

@Test
public void testValue() throws Exception{
Account account = new Account();
account.setBalance(10.01);
account.setDetails("xxoo");
MessagePack messagePack = new MessagePack();
messagePack.register(Account.class);
byte[] bs = messagePack.write(account);
System.out.println(bs.length);
Value value = messagePack.read(bs);
Account seAccount = new Converter(messagePack,value).read(Account.class);
System.out.println(seAccount);
}

本文转载自:http://blog.csdn.net/woshiliufeng/article/details/50148677

共有 人打赏支持
cloud-coder
粉丝 248
博文 194
码字总数 141537
作品 0
广州
架构师
私信 提问
MessagePack 的 C 实现发布 1.0.0 版本

MessagePack 的 C 实现发布 1.0.0 版本,下载地址:https://github.com/msgpack/msgpack-c MessagePack是一个基于二进制高效的对象序列化类库,可用于跨语言通信。它可以像JSON那样,在许多种...

oschina
2015/03/11
2.1K
2
基于.NET CORE微服务框架 -谈谈surging 的messagepack、protobuffer、json.net 序列化

1、前言 surging内部使用的是高性能RPC远程服务调用,如果用json.net序列化肯定性能上达不到最优,所以后面扩展了protobuf,messagepack序列化组件,以支持RPC二进制传输. 在这里需要感谢白纸...

fanly11
2017/11/18
0
0
Newbe.Mahua.Framework 1.3.0,速度提升10倍

QQ自动化管理助手平台意指那些支持通过QQ进行消息收发和群员管理软件平台。使用该SDK开发可以实现一次开发,运行于多个不同平台的绝佳体验。 基于SDK开发,可以实现包含但不限于以下功能: ...

Newbe36524
2017/11/27
1K
3
mprpc —— 高性能的 Python RPC 开发库

mprpc 是一个轻量级的 MessagePack RPC 远程方法调用库。你可以用它来轻松构建一个分布式的服务器端系统,只需要少量代码,基于 gevent 和 MessagePack 开发。...

oschina
2014/06/15
34
0
二进制数据格式MessagePack:比JSON更快更轻巧

MessagePack是一种新的基于二进制的对象序列化类库。它可以像JSON那样,在许多种语言之间交换结构对象(比如移动app项目);但是它比JSON更快速也更轻巧。 MessagePack简称msgpack,官方网站...

基督山伯爵
2013/03/08
0
2

没有更多内容

加载失败,请刷新页面

加载更多

zabbix安装配置

环境 系统:centos7.5软件版本: mysql: 5.7 zabbix: 3.4.15内网: Port: 10051 IP: 192.168.2.71外网: Port: 34521 Domain: freefrp.cnAgent被动模式(默认) ...

亦漩
25分钟前
2
0
一看就能学会的H5视频推流方案

本文由云+社区发表 作者:周超 导语 随着直播平台爆发式增长,直播平台从 PC 端转战移动端,紧跟着直播的潮流,自己学习实现了一套简单的 H5 视频推流的解决方案,下面就给小伙伴们分享一下自...

腾讯云加社区
28分钟前
3
0
Spring Boot 2.X优雅停止

本文章介绍了正常关闭Spring Boot 应用程序的过程。许多开发人员和架构师总是讨论SpringBoot的应用设计、流量负载、框架和应用模式,但很少有人讨论关闭阶段。生命周期意识可以说一个真正资深...

WUBAOQUAN
39分钟前
4
0
Linux Redis 高可用之主从复制

Redis主从复制简介 和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或...

我最喜欢三大框架
45分钟前
3
0
HTML5技术分享之自动化构建工具gulp使用

gulp是是前端开发对代码进行构建的工具,是基于 Nodejs 的自动任务运行器,他能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的的测试、检查、合并、压缩、格式化、浏览器...

纤纤郡主
51分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部