Netty提供了丰富的解码器抽象基类:主要分为两类:
(1)解码字节到消息(ByteToMessageDecoder和ReplayingDecoder)
(2)解码消息到消息(MessageToMessageDecoder)
ByteToMessageDecoder
用于将字节转为信息(或其它字节序列)。
在下面的例子中,将实现从入站ByteBuf读取每个整数将其传递给pipeline中的下一个ChannalInboundHandler。
/**
* 读取四字节,解码成整形
* 继承于 ByteToMessageDecoder
*
*/
public class ToIntegerDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() >= 4) { // int是4字节
out.add(in.readInt()); // 添加到解码信息的List中
}
}
}
注意,一旦一个消息被编码或解码会自动调用ReferenceCountUtil.release(message)。如果你稍后还需要用这个引用,可以调用ReferenceCountUtil.retain(message)。
ReplayingDecoder
上面的例子读取缓冲区的数据之前需要检查缓冲区是否有足够的字节,使用ReplayingDecoder就无需自己检查。若ByteBuf中不足够的字节,则会正常读取,若没有足够的字节则会停止解码。
/**
* 读取四字节,解码成整形
* 继承于ReplayingDecoder,不需要检查缓存区是否有足够的字节
*
*/
public class ToIntegerDecoder2 extends ReplayingDecoder<Void> {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
out.add(in.readInt()); // 读取整形并添加到解码信息的List中
}
}
MessageToMessageDecoder
用于从一种消息解码为另一种消息(例如,POJO到POJO)。与上面类似
/**
* 将整形解码为字符串
* 继承于MessageToMessageDecoder
*
*/
public class IntegerToStringDecoder extends MessageToMessageDecoder<Integer> {
@Override
protected void decode(ChannelHandlerContext ctx, Integer msg, List<Object> out) throws Exception {
out.add(String.valueOf(msg)); // 将整形转换为字符串
}
}
MessageToByteEncoder
把message再转换为bytes.
package codec;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
public class IntegerToByteEncoder extends MessageToByteEncoder<Short> {
@Override
public void encode(ChannelHandlerContext ctx, Short msg, ByteBuf out)
throws Exception {
out.writeShort(msg);
}
}
MessageToMessageEncoder
POJO-》POJO
package codec;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
public class IntegerToStringEncoder extends MessageToMessageEncoder<Integer> {
@Override
public void encode(ChannelHandlerContext ctx, Integer msg,
List<Object> out) throws Exception {
out.add(String.valueOf(msg));
}
}