目录
实现encoder和decoder的方法
一、利用netty
1、实现messageToByte,使用java原生的序列化方式
2、利用netty支持的现有序列化框架
3、自定义序列化协议
二、在handler的read和write方法中直接实现
tcp拆包粘包见下篇
需求:
1、客户端向服务端发送自定义类InputParam:
public class InputParam {
private int num1;
private int num2;
}
2、服务端接受到InputParam,发送对应的OutputParam:
public class OutputParam {
private String str1;
private String str2;
}
实现encoder和decoder本质上就是序列化和反序列化。
java序列化与反序列化的介绍参考:https://blog.csdn.net/weixin_43599368/article/details/84496207
客户端解码器:(byte -> outputParam,相当于outputParam的反序列化,用ObjectInputStream)
public class ClientMessageDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List
客户端编码器:(inputParam -> byte,相当于inputParam的序列化,用ObjectOutputStream)
public class ClientMessageEncoder extends MessageToByteEncoder {
@Override
protected void encode(ChannelHandlerContext ctx, InputParam msg, ByteBuf out) throws Exception {
ObjectOutputStream o = new ObjectOutputStream(new ByteBufOutputStream(out));
o.writeObject(msg);
}
}
服务端解码器:(byte -> inputParam,相当于inputParam的反序列化,用ObjectInputStream)
public class ServerMessageDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List
服务端编码器:(outputParam -> byte,相当于outParam的序列化,用ObjectOutputStream)
public class ServerMessageEncoder extends MessageToByteEncoder {
@Override
protected void encode(ChannelHandlerContext ctx, OutputParam msg, ByteBuf out) throws Exception {
ObjectOutputStream o = new ObjectOutputStream(new ByteBufOutputStream(out));
o.writeObject(msg);
}
}
此处要用到的是MessagePack
关于MessagePack
It’s like JSON.
but fast and small.
MessagePack是一种高效的二进制序列化格式。它允许您像JSON一样在多个语言之间交换数据。但是,它更快并且更小。小整数被编码为一个字节,和典型的短字符串只需要除了字符串本身的一个额外字节。
客户端解码器:(byte -> outputParam)
public class ClientMessageDecoder extends MessageToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List
客户端编码器:(inputParam -> byte)
public class ClientMessageEncoder extends MessageToByteEncoder {
@Override
protected void encode(ChannelHandlerContext ctx, InputParam msg, ByteBuf out) throws Exception {
MessagePack msgpack = new MessagePack();
out.writeBytes(msgpack.write(msg));
}
}
服务端解码器:(byte -> inputParam)
public class ServerMessageDecoder extends MessageToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List
服务端编码器:(outputParam -> byte)
public class ServerMessageEncoder extends MessageToByteEncoder {
@Override
protected void encode(ChannelHandlerContext ctx, OutputParam msg, ByteBuf out) throws Exception {
MessagePack msgpack = new MessagePack();
out.writeBytes(msgpack.write(msg));
}
}
说明:
<1>使用MessagePack,必须要在需要序列化的model上添加@Message注解
@Message
public class InputParam {
private int num1;
private int num2;
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
@Override
public String toString() {
return "InputParam{" +
"num1=" + num1 +
", num2=" + num2 +
'}';
}
}
@Message
public class OutputParam {
private String str1;
private String str2;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
@Override
public String toString() {
return "OutputParam{" +
"str1='" + str1 + '\'' +
", str2='" + str2 + '\'' +
'}';
}
}
<2>netty内置的Encoder或者Decoder类的泛型都是源类型。
eg:解码器从byte到model,泛型是bytebuf
public class ClientMessageDecoder extends MessageToMessageDecoder
包括第一种的byteToMessageDecoder
<3>详细介绍下MessageToMessageDecoder/MessageToMessageEncoder,可以实现pojo到pojo的编解码
如Integer -> String
public class IntegerToStringDecoder extends
MessageToMessageDecoder { //1
@Override
public void decode(ChannelHandlerContext ctx, Integer msg, List
参考https://blog.csdn.net/qq_32459653/article/details/81274704
略
https://blog.csdn.net/weixin_43599368/article/details/84504440