|
| 1 | +--- |
| 2 | +article: false |
| 3 | +date: 2026-01-03 |
| 4 | +icon: fa-tags |
| 5 | +tag: |
| 6 | + - 内置 |
| 7 | + - 注解 |
| 8 | + - TLV |
| 9 | +--- |
| 10 | + |
| 11 | +# TLV 类型 |
| 12 | + |
| 13 | +## 介绍 <Badge text="0.4.0" type="tip" vertical="top"/> <Badge text="Experimental" type="danger" vertical="top" /> |
| 14 | + |
| 15 | +`TLV(Type-Length-Value)` 是一种广泛应用于二进制协议中的数据编码格式,常用于高效、灵活地序列化结构化数据。 |
| 16 | + |
| 17 | +从版本 <Badge text="0.4.0" type="tip" vertical="middle" /> 开始,**xtream-codec** 引入了对 `TLV` 类型的内置支持, |
| 18 | +允许开发者通过注解定义 `TLV` 格式的消息体。 |
| 19 | + |
| 20 | +## 示例 |
| 21 | + |
| 22 | +- [GitHub](https://github.com/hylexus/xtream-codec/blob/develop/ext/jt/jt-808-server-spring-boot-starter-reactive/src/main/java/io/github/hylexus/xtream/codec/ext/jt808/builtin/messages/request/BuiltinMessage0104SampleTLV.java) |
| 23 | +- [Gitee](https://gitee.com/hylexus/xtream-codec/blob/develop/ext/jt/jt-808-server-spring-boot-starter-reactive/src/main/java/io/github/hylexus/xtream/codec/ext/jt808/builtin/messages/request/BuiltinMessage0104SampleTLV.java) |
| 24 | + |
| 25 | +```java {27-81} |
| 26 | +/** |
| 27 | + * 查询终端参数应答 0x0104 |
| 28 | + * |
| 29 | + * @author hylexus |
| 30 | + * @since 0.4.0 |
| 31 | + * |
| 32 | + */ |
| 33 | +@Getter |
| 34 | +@Setter |
| 35 | +@Accessors(chain = true) |
| 36 | +@ToString |
| 37 | +@ApiStatus.AvailableSince("0.4.0") |
| 38 | +@Jt808ResponseBody(messageId = 0x0104, desc = "查询终端参数应答(TLV示例)") |
| 39 | +public class BuiltinMessage0104SampleTLV { |
| 40 | + /** |
| 41 | + * 对应的终端参数查询消息的流水号 |
| 42 | + */ |
| 43 | + @Preset.JtStyle.Word |
| 44 | + private int flowId; |
| 45 | + |
| 46 | + /** |
| 47 | + * 应答参数个数 |
| 48 | + */ |
| 49 | + @Preset.JtStyle.Byte |
| 50 | + private short parameterCount; |
| 51 | + |
| 52 | + @XtreamTLVFieldSequence( |
| 53 | + decoder = @XtreamTLVFieldSequence.Decoder( |
| 54 | + tag = @Key(type = KeyType.u32), |
| 55 | + length = @ValueLength(type = LengthFieldType.u8), |
| 56 | + value = @XtreamTLVFieldSequence.Value( |
| 57 | + matchers = { |
| 58 | + @ValueMatcher( |
| 59 | + matchU32 = { |
| 60 | + 0x0001L, 0x0002L, 0x0003L, 0x0004L, 0x0005L, 0x0006L, 0x0007L, |
| 61 | + 0x001BL, 0x001CL, |
| 62 | + 0x0020L, 0x0021L, 0x0022L, |
| 63 | + 0x0027L, 0x0028L, 0x0029L, |
| 64 | + 0x002CL, 0x002DL, 0x002EL, 0x002FL, 0x0030L, |
| 65 | + }, |
| 66 | + valueType = XtreamDataType.u32 |
| 67 | + ), |
| 68 | + @ValueMatcher( |
| 69 | + matchU32 = { |
| 70 | + 0x0045L, 0x0046L, 0x0047L, |
| 71 | + 0x0050L, 0x0051L, 0x0052L, 0x0053L, 0x0054L, 0x0055L, |
| 72 | + 0x0056L, 0x0057L, 0x0058L, 0x0059L, 0x005AL, |
| 73 | + 0x0064L, 0x0065L, |
| 74 | + 0x0070L, 0x0071L, 0x0072L, 0x0073L, 0x0074L, |
| 75 | + 0x0080L, 0x0093L, 0x0095L, 0x0100L, 0x0102L, |
| 76 | + }, |
| 77 | + valueType = XtreamDataType.u32 |
| 78 | + ), |
| 79 | + @ValueMatcher( |
| 80 | + matchU32 = { |
| 81 | + 0x0011L, 0x0012L, 0x0013L, 0x0014L, 0x0015L, 0x0016L, 0x0017L, |
| 82 | + 0x001AL, 0x001DL, |
| 83 | + 0x0023L, 0x0024L, 0x0025L, 0x0026L, |
| 84 | + 0x0032L, |
| 85 | + 0x0040L, 0x0041L, 0x0042L, 0x0043L, 0x0044L, |
| 86 | + }, |
| 87 | + valueType = XtreamDataType.string_gbk |
| 88 | + ), |
| 89 | + @ValueMatcher(matchU32 = {0x0048L, 0x0049L, 0x0083L,}, valueType = XtreamDataType.string_gbk), |
| 90 | + @ValueMatcher(matchU32 = 0x0010L, valueType = XtreamDataType.string_gbk), |
| 91 | + @ValueMatcher(matchU32 = 0x0031L, valueType = XtreamDataType.u16), |
| 92 | + @ValueMatcher( |
| 93 | + matchU32 = { |
| 94 | + 0x005BL, 0x005CL, 0x005DL, 0x005EL, |
| 95 | + 0x0081L, 0x0082L, 0x0101L, 0x0103L, |
| 96 | + }, |
| 97 | + valueType = XtreamDataType.u16 |
| 98 | + ), |
| 99 | + @ValueMatcher(matchU32 = {0x0084L, 0x0090L, 0x0091L, 0x0092L, 0x0094L,}, valueType = XtreamDataType.u8) |
| 100 | + }, |
| 101 | + // 其他没匹配到的参数 都解析为 hexString |
| 102 | + fallbackMatchers = @FallbackValueMatcher(valueType = XtreamDataType.string_hex) |
| 103 | + ) |
| 104 | + ) |
| 105 | + ) |
| 106 | + private List<TLV> parameterItems; |
| 107 | +} |
| 108 | +``` |
0 commit comments