本文就常见的几种序列化协议介绍下简单的实践
ProtoBuf
ProtoBuf 是有谷歌开源,可以跨语言,可编译成各种语言。可称之为一个IDL, Interface description language.
- 下载编译器,protoc protoc-3.11.4-osx-x86_64.zip;可下载不同操作系统的版本, https://github.com/google/protobuf/releases
- 设置环境变量
vi ~/.bash_profile
export PATH=$PATH:/path/to/protoc-3.4.0/bin
- 在maven项目中引入相关依赖
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.11.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.googlecode.protobuf-java-format/protobuf-java-format -->
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.4</version>
</dependency>
- 编写协议文件,扩展名为proto
syntax = "proto2";
package com.seandde.test;
option optimize_for = SPEED;
option java_package = "com.seandde.test.protobuf";
option java_outer_classname = "DataInfo";
message Student {
required string name =1;
required int32 age = 2;
optional string address = 3;
}
- 使用protoc生成对应的java类
protoc --java_out=src/main/java src/protobuf/Student.proto
- 简单测试下
public class ProtoBufTest {
public static void main(String ...arg) throws Exception {
DataInfo.Student student = DataInfo.Student.newBuilder().setName("张三").setAge(28).setAddress("北京").build();
System.out.println(student);
//转换成字节可以在网络上传输
byte[] stdent2ByteArray = student.toByteArray();
//转换成java对象
DataInfo.Student student2 = DataInfo.Student.parseFrom(stdent2ByteArray);
System.out.println(student2);
}
}
相关链接: https://developers.google.com/protocol-buffers/docs/overview https://developers.google.com/protocol-buffers/docs/javatutorial
JSON , 此处使用alibaba的fastJson
- 引入相关依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
- 编写测试类
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class FastJsonTest {
public static void main(String[] args) {
Student student = new Student();
student.setAge(11);
student.setName("张数");
String result = JSON.toJSONString(student);
System.out.println(result);
Student student1 = JSON.parseObject(result, Student.class);
System.out.println(student1);
}
}
相关链接: https://github.com/alibaba/fastjson
MsgPack
注意: msgpack序列化时未记录字段名称,而是使用的数组,按字段顺序记录,因此,在bean中增加字段时需要加载bean的最后面. 使用时,可提前编译好各种msgpack模板,提升序列化、反序列化性能
- 引入相关依赖
<!-- https://mvnrepository.com/artifact/org.msgpack/msgpack -->
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.12</version>
</dependency>
- 编写相关测试
public class MsgPackTest {
public static void main(String[] args) throws IOException {
MessagePack messagePack = new MessagePack();
Student student = new Student();
student.setName("zhangsan");
student.setAge(11);
byte[] result = messagePack.write(student);
System.out.println(result);
Student student1 = messagePack.read(result, Student.class);
System.out.println(student1);
// Create serialize objects.
List<String> src = new ArrayList<String>();
src.add("msgpack");
src.add("kumofs");
src.add("viver");
// Serialize
byte[] raw = msgpack.write(src);
// Deserialize directly using a template
List<String> dst1 = msgpack.read(raw, Templates.tList(Templates.TString));
System.out.println(dst1.get(0));
System.out.println(dst1.get(1));
System.out.println(dst1.get(2));
// Or, Deserialze to Value then convert type.
Value dynamic = msgpack.read(raw);
List<String> dst2 = new Converter(dynamic)
.read(Templates.tList(Templates.TString));
System.out.println(dst2.get(0));
System.out.println(dst2.get(1));
System.out.println(dst2.get(2));
}
}
相关链接: https://msgpack.org/
hessian
hessian不同于msgpack,其记录了字段名称,因此性能可能会稍微差一些
- 引入相关依赖
<!-- https://mvnrepository.com/artifact/com.caucho/hessian -->
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.63</version>
</dependency>
- 编写测试类
public class HessianTest {
public static void main(String[] args) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(os);
output.writeObject("23456789");
output.close();
ByteArrayInputStream in = new ByteArrayInputStream(os.toByteArray());
Hessian2Input input = new Hessian2Input(in);
System.out.println(input.readObject());
}
}
相关链接: http://hessian.caucho.com/doc/hessian-serialization.html
总结
在选择序列化框架时,需考虑性能、支持的范围(如泛华、父子类)、集合类型是否会丢失等等。
欢迎关注我的公众号: 张恒强的学习笔记
来源:oschina
链接:https://my.oschina.net/838900801/blog/3210681