• admin
  • 994
  • 2026-01-02 15:39:08

为什么需要“二次”编解码?

假设我们把解决半包粘包问题的常用三种解码器叫一次解码器

那么我们在项目中,除了可选的的压缩解压缩之外,还需要一层解码,因为一次解码的结果是字节,需要和项目中所使用的对象做转化,方便使用,这层解码器可以称为“二次解码器”,相应的,对应的编码器是为了将 Java 对象转化成字节流方便存储或传输。

一次解码器:ByteToMessageDecoder

• io.netty.buffer.ByteBuf (原始数据流)-> io.netty.buffer.ByteBuf (用户数据)

二次解码器:MessageToMessageDecoder

• io.netty.buffer.ByteBuf (用户数据)-> Java Object

常用的“二次”编解码方式

Java 序列化MarshalingXMLJSONMessagePackProtobuf其他

源码解读

JsonObjectDecoder继承自ByteToMessageDecoder而不是MessageToMessageDecoder的原因

JsonObjectDecoder继承自ByteToMessageDecoder而不是MessageToMessageDecoder的原因是,JsonObjectDecoder需要直接从ByteBuf转换成Json Object对象。这是因为在网络传输过程中,数据是以二进制形式传输的,而ByteToMessageDecoder是一种ChannelInboundHandler,负责将二进制字节流(ByteBuf)转换成一种Message。

JsonObjectDecoder的解析逻辑比较简单,主要是读取ByteBuf中的数据,通过判断读取的数据和json中特有的大括号,中括号,逗号等分隔符来分割和解析json对象。这就需要ByteToMessageDecoder的能力,即从字节流中解码出消息。

另外,JsonObjectDecoder要解码的ByteBuf中的消息应该是UTF-8编码格式的。这是因为json中那些特有的分隔符,即使在UTF-8中也是用一个byte来存储的,这样我们在读取数据的过程中,可以通过读取的byte值和json的分隔符进行比较,从而来确定json中不同对象的界限。

总的来说,JsonObjectDecoder继承自ByteToMessageDecoder是因为它需要直接从字节流中解析出json对象,这是ByteToMessageDecoder所擅长的。而MessageToMessageDecoder则更适合于已经解码为某种消息的情况,需要进一步转换为另一种消息。在JsonObjectDecoder的场景中,我们需要的是从字节流直接解析出json对象,因此选择了ByteToMessageDecoder。