目录
JDK原生的序列化
字符串获取字节流
Protobuf
Protostuff
Thrift
kryo
hessian
fst
JSON字符串序列化
Jackson
Gson
FastJson
序列化和反序列化在网络传输过程中需要做的事情。
序列化 就是得的 字节流,反序列化就是得的对象。
下面梳理Java编程需要用到的一些序列化技术。有些 序列化技术 不是简单的API调用,做了一些说明。其他一些简单的API调用只是提一下。
java.io.ObjectInputStream
java.io.ObjectOutputStream
JDK的String 可以直接获取的 字节流 ,所以 最简单的就是 得到 字符串,比如Json字符串,直接调用 字符串的 getBytes方法 获取字节流。 那么也可以直接通过 String 的 构造方法 直接将字节流得的字符串
// 序列化
java.lang.String#getBytes()
// 反序列化
public String(byte bytes[], Charset charset) {
this(bytes, 0, bytes.length, charset);
}
使用 protobuf,首先需要创建 .proto 文件, 该文件 定义了 将 序列化的 结构 数据。
需要根据 规范 来创建 定义 .proto 文件,这个是首先需要 掌握的。
可以封装到公共的包来使用
步骤:
1. 创建 .proto 文件
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.wxj.grpctest.auto";
message RequestWxj {
string name = 1;
}
2. protoc 生成 代码 或者 maven 插件生成代码
3. 使用,比如 使用 proto文件 生成了一个RequestWxj,就可以来完成 数据的序列化反序列化
// 序列化 RequestWxj.newBuilder().build().toByteArray(); // 反序列化 RequestWxj.parseFrom(new byte[10]);
总结: protobuf 完成序列化和反序列化,就是 根据 .proto文件 生成了 目标 类文件,这个类文件 具有序列化和反序列化的功能,当然,是 protobuf 在生成类文件时 自动加上的功能,有了这些功能,就可以用这个类进行序列化和反序列化操作。
官网
Apache Thrift - Home
Thrift 应该不是专门用来完成序列化反序列化的,他提供的是 RPC 的服务,简单示例如下:
1. 需要安装 thrift 工具包软件,用来生成 代码,可在官网下载
2. 项目添加maven依赖
org.apache.thrift
libthrift
0.16.0
3. 编写 .thrift文件
namespace java wxj.test.serializertest.thrift
struct MyPerson{
1:optional string userName;
}
service MyThriftService{
MyPerson hello(1:MyPerson myPerson);
}
4. 根据 .thrift 生成 代码
thrift-0.16.0.exe -o F:\code\src\main\java -gen java F:\code\src\main\java\wxj\test\serializertest\thrift\Persion.thrift
可以用 -help来查看 具体用法
5. 说明一下生产的代码 怎么来使用
服务端:
public class MyServer implements MyThriftService.Iface{
@Override
public MyPerson hello(MyPerson myPerson) throws TException {
System.out.println("MyServer exe :" + myPerson);
return myPerson;
}
}
服务端启动:
public static void main(String[] args) throws Exception{
TNonblockingServerSocket serverSocket =new TNonblockingServerSocket(8803);
THsHaServer.Args arg=new THsHaServer.Args(serverSocket).maxWorkerThreads(4).minWorkerThreads(2);
MyThriftService.Processor processor =new MyThriftService.Processor<>(new MyServer());
arg.protocolFactory(new TCompactProtocol.Factory());
arg.transportFactory(new TFastFramedTransport.Factory());
arg.processorFactory(new TProcessorFactory(processor));
TServer tServer = new THsHaServer(arg);
System.out.println("Running Simple Server");
tServer.serve();
客户端:
TTransport transport =null;
try {
transport = new TFramedTransport(new TSocket("127.0.0.1",8803),600);
TProtocol protocol = new TCompactProtocol(transport);
MyThriftService.Client client = new MyThriftService.Client(protocol);
transport.open();
MyPerson myPerson = new MyPerson();
myPerson.setUserName("jack");
MyPerson result = client.hello(myPerson);
} catch (TException e) {
e.printStackTrace();
} finally {
transport.close();
}
如果会使用 protobuf,那么 理解 thrift 也不难。 同样需要 自定义文件,同样需要根据自定义文件来生成代码,同样是使用生成的代码来完成具体功能。
上面的几种序列化方式,是直接将字节流反序列化成不同的对象 或者 不同的对象 序列化成字节流。
现在 服务之间数据传输是使用 JSON 格式。
序列化之前 先转为JSON 字符串,再将字符串序列化成字节流;
反序列化时,是将字节流反序列化成JSON字符串,再将JSON字符串 转为对象
pom.xml 依赖
这个依赖会自动引入另外两个模块的依赖包
com.fasterxml.jackson.core
jackson-databind
2.13.3
compile
使用
// 核心代码
ObjectMapper objectMapper = new ObjectMapper();
// 序列化
objectMapper.writeValueAsBytes(t);
// 反序列化
objectMapper.readValue