实体编解码器调试
2025/3/2小于 1 分钟
实体编解码器调试
介绍
只需要给 EntityCodec 的 encode 或 decode 方法传入一个 CodecTracker 实例即可追踪每个字段的编解码详情。
注意
警告
CodecTracker 的设计目的仅仅是用来调试。 会对编解码性能产生 严重 影响。
示例
class EntityCodecWithTrackerTest {
@Getter
@Setter
@ToString
@Accessors(chain = true)
public static class UserEntity {
@Preset.RustStyle.u32(desc = "用户ID(32位无符号数)")
private Long id;
// prependLengthFieldType: 前置一个 u8 类型的字段表示当前字段的长度
@Preset.RustStyle.str(prependLengthFieldType = PrependLengthFieldType.u8, desc = "用户名")
private String name;
@Preset.RustStyle.u16(desc = "年龄(16位无符号数)")
private Integer age;
// prependLengthFieldType: 前置一个 u8 类型的字段表示当前字段的长度
@Preset.RustStyle.str(prependLengthFieldType = PrependLengthFieldType.u8, desc = "地址")
private String address;
}
EntityCodec entityCodec = EntityCodec.DEFAULT;
@Test
void testEncode() {
final UserEntity userEntity = new UserEntity()
.setId(1024L)
.setName("无名氏")
.setAge(2048)
.setAddress("保密");
final ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
try {
final CodecTracker tracker = new CodecTracker();
// 将实体对象编码到 buffer 中
this.entityCodec.encode(userEntity, buffer, tracker);
// 访问(遍历)tracker 默认使用 System.out.println 输出到控制台
tracker.visit();
final String hexString = FormatUtils.toHexString(buffer);
assertEquals("0000040009e697a0e5908de6b08f080006e4bf9de5af86", hexString);
} finally {
buffer.release();
assertEquals(0, buffer.refCnt());
}
}
@Test
void testDecode() {
final ByteBuf buffer = XtreamBytes.byteBufFromHexString(ByteBufAllocator.DEFAULT, "0000040009e697a0e5908de6b08f080006e4bf9de5af86");
try {
final CodecTracker tracker = new CodecTracker();
// 将数据从 buffer 中解码到实体对象
final UserEntity entity = this.entityCodec.decode(UserEntity.class, buffer, tracker);
// 访问(遍历)tracker 默认使用 System.out.println 输出到控制台
tracker.visit();
assertEquals(1024L, entity.getId());
assertEquals("无名氏", entity.getName());
assertEquals(2048, entity.getAge());
assertEquals("保密", entity.getAddress());
} finally {
buffer.release();
assertEquals(0, buffer.refCnt());
}
}
}输出效果
[==> 0] CodecTraceNode[kind=ROOT, name='root', path='', javaType='io.github.hylexus.xtream.codec.core.EntityCodecWithTrackerTest$UserEntity', processorType='null', value=null, byteRange=0-23, hex='0000040009e697a0e5908de6b08f080006e4bf9de5af86', status=SUCCESS]
[==> 1] CodecTraceNode[kind=FIELD, name='id', path='id', javaType='null', processorType='U32FieldCodec', value=1024, byteRange=0-4, hex='00000400', status=SUCCESS]
[==> 1] CodecTraceNode[kind=LENGTH_FIELD, name='prependLengthField', path='prependLengthField', javaType='null', processorType='u8', value=9, byteRange=4-5, hex='09', status=SUCCESS]
[==> 1] CodecTraceNode[kind=FIELD, name='name', path='name', javaType='null', processorType='StringFieldCodec', value=无名氏, byteRange=5-14, hex='e697a0e5908de6b08f', status=SUCCESS]
[==> 1] CodecTraceNode[kind=FIELD, name='age', path='age', javaType='null', processorType='U16FieldCodec', value=2048, byteRange=14-16, hex='0800', status=SUCCESS]
[==> 1] CodecTraceNode[kind=LENGTH_FIELD, name='prependLengthField', path='prependLengthField', javaType='null', processorType='u8', value=6, byteRange=16-17, hex='06', status=SUCCESS]
[==> 1] CodecTraceNode[kind=FIELD, name='address', path='address', javaType='null', processorType='StringFieldCodec', value=保密, byteRange=17-23, hex='e4bf9de5af86', status=SUCCESS]