netty是区别于以往的传输方式,通过字节来传输。
编码器和解码器主要用于解析,加密,可以按自己的逻辑去实现数据的传输格式,可以自定义协议。
通过ChannelPipeline对象可以向链路中添加 解码器和编码器
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(
new RequestDataEncoder(),
new ResponseDataDecoder(),
new ClientHandler());
RequestDataEncoder 编码器(继承MessageToByteEncoder)
public class RequestDataEncoder extends MessageToByteEncoder<RequestData> {
//设置编码格式
private final Charset charset = StandardCharsets.UTF_8;
@Override
protected void encode(ChannelHandlerContext ctx, RequestData msg, ByteBuf out) throws Exception {
// int i = ByteBufUtil.writeUtf8(out, msg.getStringValue());
//数据msg.getIntValue(),写入out,以int类型,占4个字节宽度
out.writeInt(msg.getIntValue());
//msg.getStringValue() 数据如果是中文每个占3个字节,如果是英文字母每个占2个字节
//所以我们将它转为字节数组,获取他的长度
byte[] bytes = msg.getStringValue().getBytes();
//将msg.getStringValue() 的值字节长度,写入out,以int类型占4个字节宽度
out.writeInt(bytes.length);
//将msg.getStringValue() 的值,写入our,以字符类型,utf-8的格式写入
out.writeCharSequence(msg.getStringValue(), charset);
}
}
ResponseDataDecoder 解码器 (继承ReplayingDecoder)
public class RequestDecoder extends ReplayingDecoder<RequestData> {
private final Charset charset = StandardCharsets.UTF_8;
@Override
protected void decode(ChannelHandlerContext ctx,
ByteBuf in, List<Object> out) throws Exception {
RequestData data = new RequestData();
//读取in里的 [0,4) readerIndex = 0,readerIndex+4 范围内的字节数据,并且读取后 readerIndex=4
int i = in.readInt();
data.setIntValue(i);
//读取in里的 [4,8) readerIndex = 4,readerIndex+4 范围内的字节数据,并且读取后 readerIndex=8
//strLen 就是上面编码器,msg.getStringValue()值占的字节长度。
int strLen = in.readInt();
//读取in里strLen长度的字符序列(readerIndex=8,readerIndex + strLen),并转换为utf-8编码格式
CharSequence charSequence = in.readCharSequence(strLen, charset);
//解码器解析出的msg.getStringValue() 的值为 charSequence.toString()
data.setStringValue(charSequence.toString());
out.add(data);
}
}