Java 全JT/T808 数据类型 + 校验码 + 转义 + 分包

张开发
2026/6/2 7:47:40 15 分钟阅读
Java 全JT/T808 数据类型 + 校验码 + 转义 + 分包
一、注解与枚举import java.lang.annotation.*; Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) Documented public interface Jt808Field { Jt808Type type(); int length() default 0; } // 808全数据类型枚举 public enum Jt808Type { BYTE, WORD, DWORD, BYTES, BCD, STRING }二、全类型消息类public class Jt808FullTypeMessage { Jt808Field(type Jt808Type.BYTE) private int command; Jt808Field(type Jt808Type.WORD) private int msgId; Jt808Field(type Jt808Type.DWORD) private long data; Jt808Field(type Jt808Type.BYTES, length 6) private byte[] reserve; Jt808Field(type Jt808Type.BCD, length 6) private String terminalPhone; Jt808Field(type Jt808Type.BCD, length 6) private String time; Jt808Field(type Jt808Type.STRING, length 16) private String content; // getter setter public int getCommand() { return command; } public void setCommand(int command) { this.command command; } public int getMsgId() { return msgId; } public void setMsgId(int msgId) { this.msgId msgId; } public long getData() { return data; } public void setData(long data) { this.data data; } public byte[] getReserve() { return reserve; } public void setReserve(byte[] reserve) { this.reserve reserve; } public String getTerminalPhone() { return terminalPhone; } public void setTerminalPhone(String terminalPhone) { this.terminalPhone terminalPhone; } public String getTime() { return time; } public void setTime(String time) { this.time time; } public String getContent() { return content; } public void setContent(String content) { this.content content; } }三、核心编码解码类import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.lang.reflect.Field; import java.nio.charset.Charset; public class Jt808Codec { public static final byte FLAG 0x7E; public static final byte ESCAPE 0x7D; public static final int MAX_BODY_LENGTH 1023; // 编码 public static ByteBuf encode(Object obj) throws Exception { ByteBuf buf Unpooled.buffer(); Class? clazz obj.getClass(); Field[] fields clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); Object value field.get(obj); Jt808Field anno field.getAnnotation(Jt808Field.class); if (anno null) continue; // JDK8 传统 switch switch (anno.type()) { case BYTE: writeByte(buf, (Integer) value); break; case WORD: writeWord(buf, (Integer) value); break; case DWORD: writeDword(buf, (Long) value); break; case BYTES: writeBytes(buf, (byte[]) value, anno.length()); break; case BCD: writeBcd(buf, (String) value, anno.length()); break; case STRING: writeString(buf, (String) value, anno.length()); break; } } return buf; } // 解码 public static T T decode(ByteBuf buf, ClassT clazz) throws Exception { T obj clazz.newInstance(); Field[] fields clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); Jt808Field anno field.getAnnotation(Jt808Field.class); if (anno null) continue; Object value null; // JDK8 switch switch (anno.type()) { case BYTE: value buf.readUnsignedByte(); break; case WORD: value buf.readUnsignedShort(); break; case DWORD: value buf.readUnsignedInt(); break; case BYTES: value readBytes(buf, anno.length()); break; case BCD: value readBcd(buf, anno.length()); break; case STRING: value readString(buf, anno.length()); break; } field.set(obj, value); } return obj; } // 基础类型 private static void writeByte(ByteBuf buf, int value) { buf.writeByte(value 0xFF); } private static void writeWord(ByteBuf buf, int value) { buf.writeShort(value 0xFFFF); } private static void writeDword(ByteBuf buf, long value) { buf.writeInt((int) (value 0xFFFFFFFFL)); } // BYTE[] private static void writeBytes(ByteBuf buf, byte[] value, int len) { if (value null) value new byte[len]; int writeLen Math.min(value.length, len); buf.writeBytes(value, 0, writeLen); for (int i writeLen; i len; i) buf.writeByte(0); } private static byte[] readBytes(ByteBuf buf, int len) { byte[] bytes new byte[len]; buf.readBytes(bytes); return bytes; } // BCD private static void writeBcd(ByteBuf buf, String value, int len) { if (value null) value ; String num value.replaceAll([^0-9], ); int need len * 2; while (num.length() need) num 0 num; num num.substring(num.length() - need); for (int i 0; i need; i 2) { int h num.charAt(i) - 0; int l num.charAt(i 1) - 0; buf.writeByte((h 4) | l); } } private static String readBcd(ByteBuf buf, int len) { StringBuilder sb new StringBuilder(); for (int i 0; i len; i) { byte b buf.readByte(); sb.append((b 4) 0x0F).append(b 0x0F); } return sb.toString(); } // STRING(GBK) private static void writeString(ByteBuf buf, String s, int len) { if (s null) s ; byte[] data s.getBytes(Charset.forName(GBK)); int wl Math.min(data.length, len); buf.writeBytes(data, 0, wl); for (int i wl; i len; i) buf.writeByte(0); } private static String readString(ByteBuf buf, int len) { byte[] data new byte[len]; buf.readBytes(data); int i 0; while (i len data[i] ! 0) i; return new String(data, 0, i, Charset.forName(GBK)); } // 校验码 public static byte calculateXor(ByteBuf buf) { byte xor 0; while (buf.isReadable()) { xor ^ buf.readByte(); } return xor; } // 转义 public static byte[] escape(byte[] data) { ByteBuf buf Unpooled.buffer(); for (byte b : data) { if (b FLAG) { buf.writeByte(ESCAPE); buf.writeByte(0x02); } else if (b ESCAPE) { buf.writeByte(ESCAPE); buf.writeByte(0x01); } else { buf.writeByte(b); } } byte[] res new byte[buf.readableBytes()]; buf.readBytes(res); buf.release(); return res; } // 反转义 public static byte[] unescape(byte[] data) { ByteBuf buf Unpooled.buffer(); for (int i 0; i data.length; i) { if (data[i] ESCAPE i 1 data.length) { if (data[i 1] 0x01) buf.writeByte(ESCAPE); else if (data[i 1] 0x02) buf.writeByte(FLAG); i; } else { buf.writeByte(data[i]); } } byte[] res new byte[buf.readableBytes()]; buf.readBytes(res); buf.release(); return res; } }四、测试import io.netty.buffer.ByteBuf; public class Jt808Test { public static void main(String[] args) throws Exception { // 构造消息 Jt808FullTypeMessage msg new Jt808FullTypeMessage(); msg.setCommand(0x05); msg.setMsgId(0x0200); msg.setData(0x12345678L); msg.setReserve(new byte[]{1,2,3,4,5,6}); msg.setTerminalPhone(13800138000); msg.setTime(20260320123456); msg.setContent(测试JT808协议); // 编码 ByteBuf buf Jt808Codec.encode(msg); System.out.println(编码长度 buf.readableBytes()); // 解码 Jt808FullTypeMessage result Jt808Codec.decode(buf, Jt808FullTypeMessage.class); // 输出 System.out.println(手机号 result.getTerminalPhone()); System.out.println(时间 result.getTime()); System.out.println(内容 result.getContent()); } }

更多文章