java 序列化协议_【微服务】序列化协议 In Action

本文就常见的几种序列化协议介绍下简单的实践

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项目中引入相关依赖

com.google.protobuf

protobuf-java

3.11.4

com.googlecode.protobuf-java-format

protobuf-java-format

1.4

编写协议文件,扩展名为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);

}

}

JSON , 此处使用alibaba的fastJson

引入相关依赖

com.alibaba

fastjson

1.2.62

编写测试类

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);

}

}

MsgPack

注意: msgpack序列化时未记录字段名称,而是使用的数组,按字段顺序记录,因此,在bean中增加字段时需要加载bean的最后面. 使用时,可提前编译好各种msgpack模板,提升序列化、反序列化性能

引入相关依赖

org.msgpack

msgpack

0.6.12

编写相关测试

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 src = new ArrayList();

src.add("msgpack");

src.add("kumofs");

src.add("viver");

// Serialize

byte[] raw = msgpack.write(src);

// Deserialize directly using a template

List 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 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));

}

}

hessian

hessian不同于msgpack,其记录了字段名称,因此性能可能会稍微差一些

引入相关依赖

com.caucho

hessian

4.0.63

编写测试类

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());

}

}

总结

在选择序列化框架时,需考虑性能、支持的范围(如泛华、父子类)、集合类型是否会丢失等等。

欢迎关注我的公众号: 张恒强的学习笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值