Netty——Netty编解码器
前言
在了解Netty编解码之前,先了解Java的编解码:
-
编码(Encode) 称为序列化, 它将对象序列化为字节数组,用于网络传输、数据持久化或者其它用途。
-
解码(Decode) 称为反序列化,它把从网络、磁盘等读取的字节数组还原成原始对象(通常是原始对象的拷贝),以方便后续的业务逻辑操作。
java序列化对象只需要实现java.io.Serializable
接口并生成序列化ID,这个类就能够通过java.io.ObjectInput
和java.io.ObjectOutput
序列化和反序列化。
Java序列化目的:
- 1、网络传输。
- 2、对象持久化。
Java序列化缺点:
- 1、无法跨语言。
- 2、序列化后码流太大。
- 3、序列化性能太低。
Java序列化仅仅是Java编解码技术的一种,由于它的种种缺陷,衍生出了多种编解码技术和框架,这些编解码框架实现消息的高效序列化。
下面我们来了解下Netty自己的编解码器。
一、概念
在网络应用中需要实现某种编解码器,将原始字节数据与自定义的消息对象进行互相转换。网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码。
netty提供了强大的编解码器框架,使得我们编写自定义的编解码器很容易,也容易封装重用。对于Netty而言,编解码器由两部分组成:编码器、解码器。
- 解码器:负责将消息从字节或其他序列形式转成指定的消息对象。
- 编码器:将消息对象转成字节或其他序列形式在网络上传输。
Netty 的编(解)码器实现了 ChannelHandlerAdapter,也是一种特殊的ChannelHandler,所以依赖于 ChannelPipeline,可以将多个编(解)码器链接在一起,以实现复杂的转换逻辑。
Netty里面的编解码:
- 解码器:负责处理“入站 InboundHandler”数据。
- 编码器:负责“出站 OutboundHandler” 数据。
二、解码器(Decoder)
解码器负责 解码“入站”数据从一种格式到另一种格式,解码器处理入站数据是抽象ChannelInboundHandler的实现。实践中使用解码器很简单,就是将入站数据转换格式后传递到ChannelPipeline中的下一个ChannelInboundHandler进行处理;这样在处理时很灵活的,我们可以将解码器放在ChannelPipeline中,重用逻辑。
对于解码器,Netty中主要提供了抽象基类ByteToMessageDecoder和MessageToMessageDecoder。
抽象解码器
-
1、ByteToMessageDecoder:用于将字节转为消息,需要检查缓冲区是否有足够的字节。
-
2、ReplayingDecoder:继承ByteToMessageDecoder,不需要检查缓冲区是否有足够的字节,但是 ReplayingDecoder速度略慢于ByteToMessageDecoder,同时不是所有的ByteBuf都支持。 选择:项目复杂性高则使用ReplayingDecoder,否则使用 ByteToMessageDecoder。
-
3、MessageToMessageDecoder:用于从一种消息解码为另外一种消息(例如POJO到POJO)。
1、ByteToMessageDecoder解码器
用于将接收到的二进制数据(Byte)解码,得到完整的请求报文(Message)。
ByteToMessageDecoder是一种ChannelInboundHandler,可以称为解码器,负责将byte字节流住(ByteBuf)转换成一种Message,Message是应用可以自己定义的一种Java对象。
下面列出了ByteToMessageDecoder两个主要方法:
protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)//这个方法是唯一的一个需要自己实现的抽象方法,作用是将ByteBuf数据解码成其他形式的数据。 decodeLast(ChannelHandlerContext, ByteBuf, List<Object>),//实际上调用的是decode(...)。