Java的序列化
Java提供的序列化机制,涉及到两个对象输入输出流类,ObjectInputStream,ObjectOutputStream。
Java序列化的目的是网络传输和对象持久化。
序列化,在网络传输中,将Java对象编码为字节数组或者ByteBuffer对象
反序列化,将从远程服务读取到的ByteBuffer对象或者字节数组解码为Java对象。
Java序列化的缺点:
1、无法跨语言
2、序列化后的码流太大
3、序列化性能差
Protobuf
Protobuf使用二进制编码
平台无关的数据描述文件
优秀的代码生成机制
Protobuf使用和整合Netty开发
下载地址:https://github.com/protocolbuffers/protobuf/releases
IDEA有protobuf代码生成插件,Maven也有,但是我试了不太好用。
我的IDEA是2018.3.1,几款IDEA插件安装了都没有效果。
Maven插件网上也搜了,试了,但是没有成功。想来这些插件只是为了提升生产力的一种途径,就不折腾了。
实验的代码,是使用官网软件的命令行方式生成的代码。
Netty的protobuf服务端:
SubReqServerHandler.java
Netty的protobuf客户端:
SubReqClientHandler.java
public class SubReqClientHandler extends ChannelInboundHandlerAdapter {
/**
* Creates a client-side handler.
*/
public SubReqClientHandler() {
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
for (int i = 0; i < 10; i++) {
ctx.write(subReq(i));
}
ctx.flush();
}
private SubscribeReqProto.SubscribeReq subReq(int i) {
SubscribeReqProto.SubscribeReq.Builder builder = SubscribeReqProto.SubscribeReq
.newBuilder();
builder.setSubReqID(i);
builder.setUserName("Lilinfeng");
builder.setProductName("Netty Book For Protobuf");
List<String> address = new ArrayList<>();
address.add("NanJing YuHuaTai");
address.add("BeiJing LiuLiChang");
address.add("ShenZhen HongShuLin");
builder.addAllAddress(address);
return builder.build();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
System.out.println("Receive server response : [" + msg + "]");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
注意到,使用Netty的protobuf开发客户端和服务端,主要是在代码里面用了几个特殊的编解码器,这里不细说这些编解码器的作用,可以参见对应的JAVA DOC。
Netty还提供了很多其他的编解码器,对很多种序列化方式提供支持,都在io.netty.handler.codec包下。
Protobuf使用注意事项:
ProtobufDecoder仅仅负责解码,不能读半包。需要在解码前处理半包消息,有三种方式:
1、使用ProtobufVarint32FrameDecoder
2、继承通用半包处理器LengthFieldBasedFrameDecoder
3、继承ByteToMessageDecoder自己处理半包
总结:
这篇文章,从Java序列化讲到Netty序列化的支持,以Protobuf为例演示了代码。
学完后,掌握了Netty的protobuf编程。