Comments (4)
找了很久资料,找不到对应的方式解析数据.只好自己实现了解析终端参数查询结果.
依赖版本(除了jt-framework强依赖,Java版本可自行修改代码适配低版本):
jt-framework: 2.0.0-RELEASE
Java: 17
Spring Boot(低版本可用,此处仅使用了 @component): 2.6.3
简单代码如下:
实体类:
import io.github.hylexus.jt.jt808.support.annotation.msg.req.Jt808RequestBody;
import io.github.hylexus.jt.jt808.support.annotation.msg.req.RequestField;
import io.github.hylexus.jt.jt808.support.data.MsgDataType;
import io.github.hylexus.jt.jt808.support.utils.JtProtocolUtils;
import io.netty.buffer.ByteBufAllocator;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static io.github.hylexus.jt.jt808.support.data.MsgDataType.*;
/**
* 查询终端参数应答.
*
* @author puruidong
* @version 2022-02-24
*/
@Slf4j
@Data
@Accessors(chain = true)
@Jt808RequestBody
public class TerminalParamQuery0104V2013 {
/** 1. 流水号 WORD */
@RequestField(order = 0, startIndex = 0, dataType = WORD)
int serverFlowId;
/** 2. 参数个数 */
@RequestField(order = 1, startIndex = 2, dataType = BYTE)
int count;
/** 3. 参数项列表 */
@RequestField(
order = 2,
startIndex = 3,
dataType = LIST,
lengthExpression = "#ctx.msgBodyLength() - 3")
List<TerminalParam> paramList;
@Data
@Accessors(chain = true)
public static class TerminalParam {
// 参数id DWORD[4]
@RequestField(order = 0, startIndex = 0, dataType = DWORD)
private int paramId;
// 参数长度 BYTE[1]
@RequestField(order = 1, startIndex = 2, dataType = BYTE)
private int contentLength;
// 参数值
@RequestField(
order = 2,
startIndex = 3,
dataType = BYTES,
lengthExpression = "#this.contentLength")
private byte[] paramContent;
}
/**
* 记录终端明细参数对应的值类型.
*
* <p>! 注意: 此处仅包含部分,其余未包含的参数ID,默认以DWORD类型解析.
*/
private final Map<Integer, MsgDataType> detailParamIdType =
Map.of(16, STRING, 17, STRING, 18, STRING, 19, STRING, 131, STRING, 132, BYTE);
/**
* 需要解析的参数id列表.
*
* <p>对应: 0x0001, 0x0010, 0x0013, 0x0018, 0x0027, 0x0029, 0x0055, 0x0056, 0x0080, 0x0081, 0x0082,
* 0x0083, 0x0084
*/
private final List<Integer> paramIdRequires =
List.of(1, 16, 19, 24, 39, 41, 85, 86, 128, 129, 130, 131, 132);
/**
* 解析后的参数值Map.
*
* Key为int类型的参数ID,value为参数值.
*
*/
public Map<Integer, String> detailParamMap;
/**
* 手动解析数据.
*
* 解析后的数据保存在: detailParamMap变量中,Key为int类型的参数ID,value为参数值.
*
* @return 当前实例
*/
public TerminalParamQuery0104V2013 decodeParamList() {
// 解析明细数据.
if (paramList.size() > 0) {
Map<Integer, String> resultMap = new HashMap<>(paramList.size());
paramList.forEach(
item -> {
// 仅解析已经预制的字段,除此之外的字段不解析.
if (paramIdRequires.contains(item.paramId)) {
byte[] paramContentArr = item.paramContent;
// byte[] 数组小于4位,则使用0前置填充.
if (item.paramContent.length < 4) {
paramContentArr = new byte[] {0, 0, 0, 0};
System.arraycopy(
item.paramContent,
0,
paramContentArr,
paramContentArr.length - item.paramContent.length,
item.paramContent.length);
}
var paramContentByteBuf =
ByteBufAllocator.DEFAULT.buffer().writeBytes(paramContentArr);
var checkDataType = detailParamIdType.containsKey(item.paramId);
var value = "";
if (checkDataType) {
var dataType = detailParamIdType.getOrDefault(item.paramId, STRING);
if (dataType == STRING) {
value =
JtProtocolUtils.readString(
paramContentByteBuf, item.contentLength, Charset.forName("GBK"));
} else {
// 当数据为BYTE类型时,需要使用原始数据!
paramContentByteBuf =
ByteBufAllocator.DEFAULT.buffer().writeBytes(item.paramContent);
byte by = paramContentByteBuf.readByte();
value = String.valueOf(by);
}
} else {
// 不存在,以DWORD解析.
value = String.valueOf(JtProtocolUtils.readUnsignedDword(paramContentByteBuf));
}
resultMap.put(item.getParamId(), value);
}
});
setDetailParamMap(resultMap);
}
return this;
}
}
解析调用:
import com.example.entity.TerminalParamQuery0104V2013;
import io.github.hylexus.jt.jt808.spec.Jt808Request;
import io.github.hylexus.jt.jt808.spec.Jt808RequestEntity;
import io.github.hylexus.jt.jt808.spec.builtin.msg.resp.BuiltinServerCommonReplyMsg;
import io.github.hylexus.jt.jt808.support.annotation.handler.Jt808RequestHandler;
import io.github.hylexus.jt.jt808.support.annotation.handler.Jt808RequestHandlerMapping;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 终端参数查询结果处理.
*
* @author puruidong
* @version 2022-02-24
*/
@Slf4j
@Component
@Jt808RequestHandler
public class TerminalParamQueryHandler {
@Jt808RequestHandlerMapping(msgType = 0x0104)
public BuiltinServerCommonReplyMsg terminalParamQueryResult(
Jt808Request request, Jt808RequestEntity<TerminalParamQuery0104V2013> requestEntity) {
// 执行手动转换数据.
var obj = requestEntity.body().decodeParamList();
// 解析后的数据在: detailParamMap 中,详情查看实体类.
log.info("终端参数查询处理 : {}", obj.toString());
return BuiltinServerCommonReplyMsg.success(
requestEntity.msgType().getMsgId(), requestEntity.flowId());
}
}
from jt-framework.
终端参数结果返回的是列表,但字段没有固定长度,请问应该怎么解析?谢谢.
目前为止只能使用 byte[]
或 ByteBuf
来接收这种 不确定的 数据类型,然后通过参数ID 来解析为具体类型。就像你 上面 提到一样:
@Data
@Accessors(chain = true)
public static class TerminalParam {
// 参数id DWORD[4]
@RequestField(order = 0, startIndex = 0, dataType = DWORD)
private int paramId;
// 参数长度 BYTE[1]
@RequestField(order = 1, startIndex = 2, dataType = BYTE)
private int contentLength;
// 参数值
@RequestField(
order = 2,
startIndex = 3,
dataType = BYTES,
lengthExpression = "#this.contentLength")
private byte[] paramContent;
}
from jt-framework.
如图,同时存在STRING和WORD.
from jt-framework.
同时存在BYTE.
这是我这遇到的所有需要解析的数据.
from jt-framework.
Related Issues (20)
- 附加信息。length的类型只能是Integer HOT 1
- DWORD显示应该是有问题的。 HOT 1
- 不支持2019版的消息应答? HOT 1
- handler-scan配置错误
- 麻烦同意一下qq群加入 HOT 1
- 支持808协议的哪些版本? HOT 2
- 报警标志怎么知道具体含义?
- netty报错 "refCnt: 0, decrement: 1" HOT 1
- 内存泄漏:LEAK: ByteBuf.release() was not called before it's garbage-collected HOT 1
- 服务端无法根据心跳主动断开连接 HOT 1
- 下发终端设置指令异常 HOT 1
- 是否支持JDK 8? HOT 1
- 报文解析错误 HOT 2
- 准备把Gradle升级到7.3.3,报错 HOT 1
- [Question] Logo HOT 1
- 能否安全地去掉注解的 order 属性?
- 在接收不是框架内规定范围内的jt808消息时,会抛异常 HOT 1
- 对于BCD码类型的解析BUG HOT 6
- io.netty.util.ResourceLeakDetector : LEAK: ByteBuf.release() was not called before it's garbage-collected HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jt-framework.