序列化问题
Java对象的序列化主要有两个:
网络传输
数据在网络中传输是通过字节流形式的,到服务端需要解码。
对象持久化
Java序列化
Java序列化机制是基于对象的类结构进行的。
当对象需要序列化时,会将对象转换为字节流在网络传输。
反序列化时,就是将字节流转换为对象的过程。Java会将字节流转换为对象重新加载到内存中。
Java的序列化机制是通过实现java.io.Serializable
接口来实现的。该接口是一个标记接口,没有任何方法定义。只有实现了Serializable
接口的类的对象才能被序列化。
缺点
序列化性能较低
javaThe jdk serializable cost time is : 1343 ms ------------------------------------- The byte array serializable cost time is : 128 ms
序列化后字节数组过大
javaThe jdk serializable length is : 128 The byte array serializable length is : 24
不支持跨语言,只支持Java,其它语言无法反序列化。
Protocol Buffers
java
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
/*去除消息长度部分,同时根据这个消息长度读取实际的数据*/
ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
//Protobuf进行解码,反序列化
ch.pipeline().addLast(new ProtobufDecoder(PersonProto.Person.getDefaultInstance()));
ch.pipeline().addLast(new ProtoBufServerHandler());
}
});
java
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception {
/*加一个消息长度,由netty自动计算*/
ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
//Protobuf进行编码,负责序列化
ch.pipeline().addLast(new ProtobufEncoder());
ch.pipeline().addLast(new ProtoBufClientHandler());
}
});