Java中如何将对象按指定字段顺序序列化为自定义TCP协议所需字节数组
解决方案
可选第三方库
- JBBP(Java Binary Block Parser)
专门针对固定顺序二进制字段的编解码场景设计,支持通过注解定义字段顺序、字节长度、大小端规则,序列化后直接输出纯净的byte[],不会附加任何类结构信息。你只需要给实体类的字段加上对应注解配置顺序和类型即可,无需单独为每个类编写序列化逻辑。
示例配置参考:
@JBBPEntity public class CustomTcpMessage { @JBBPField(order = 0, type = JBBPType.BYTE) private byte messageTypeFirst; @JBBPField(order = 1, type = JBBPType.BYTE) private byte messageTypeSecond; @JBBPField(order = 2, type = JBBPType.SHORT) private short length; @JBBPField(order = 3, type = JBBPType.INT, bits = 24) private int transactionId; @JBBPField(order = 4, type = JBBPType.BYTE) private byte body; // 省略getter、setter }
序列化仅需一行代码:byte[] result = JBBP.toBytes(customTcpMessageInstance);
- Struct4j
对齐C语言struct的序列化规则,支持注解配置字段顺序、字节长度、对齐方式,完全满足私有二进制协议的序列化要求,没有额外冗余信息输出。 - 基于Netty ByteBuf的轻量注解实现
如果你的项目已经引入Netty,可以自定义一套极简注解,配合反射扫描实现通用序列化:自定义@BinaryField注解标注字段的顺序、长度、大小端属性,写一个通用工具类扫描所有带注解的字段,按顺序写入ByteBuf后直接获取byte[]即可,可控性更高,性能也更好。
无依赖通用实现方案
如果不想引入第三方依赖,可以自己实现一套通用序列化逻辑,全程不超过200行代码,灵活度最高:
- 首先定义协议字段注解
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ProtocolField { // 字段排序,从小到大序列化 int order(); // 字段占字节长度 int byteLength(); // 是否为大端字节序,默认符合多数网络协议规范 boolean isBigEndian() default true; }
- 给实体类字段加注解
public class TcpMessage { @ProtocolField(order = 0, byteLength = 1) private byte msgType1; @ProtocolField(order = 1, byteLength = 1) private byte msgType2; @ProtocolField(order = 2, byteLength = 2) private short length; @ProtocolField(order = 3, byteLength = 3) private int transaction; @ProtocolField(order = 4, byteLength = 1) private byte body; // 省略getter、setter }
- 实现通用序列化工具类
核心逻辑为:反射获取目标类所有带@ProtocolField注解的字段,按order值升序排序,依次读取字段值,根据字段类型、长度、大小端规则转换为字节数组写入ByteArrayOutputStream,最终输出拼接好的byte[]即可。反序列化也可以复用同一套注解规则反向解析。
额外注意:涉及多字节数字类型时,一定要和私有协议的大小端规则对齐,避免出现数值转换错误。
内容的提问来源于stack exchange,提问作者Daniele Ravizza
相关产品推荐
相关产品推荐

