废话
还是那句话,网上搜得到的文档比和尚的头发还少,直接啃源码吧,啃了半天,终于啃到了一个类:XMLMessageTemplateLoader
没错,就是字面意思,把模板.xml文件直接转成模板对象。我主要任务就是解析,也就是数据跟模板都有现成的了,只需要通过模板把数据流解析出来就行,k看到这玩意,然后再结合上一篇的方法,应该就可以解析出来了,我仿佛看到了胜利的曙光。
在我一顿猛如虎的操作之后,现实狠狠的给我甩了一个大嘴巴子:The template with id 0 has not been registered
模板没有注册0这个模板,我一脸的懵逼啊,也没这玩意吧,网上搜了不少,最后发现了一个大佬也是研究这玩意研究了挺久的(https://github.com/kuangtu/fixfast),看了一下大佬写的示例代码,短短几行,字里行间都透漏着对生活的……跑题了,大佬写的示例代码,压根就跟我的差不多啊,为毛他的可以我的不行,总不能是数据提供方骗我,故意给我假数据吧?
数据是从上证拿的,上证给的文档,说是从STEP协议中会有一个Tag96,,这个Tag96的值就是一个FAST协议的流,然后我就从上证给的STEP协议流中将Tag96的数据拉了出来,解析,失败,解析,失败,解析失败,鬼知道我换了多少种姿势,还是没怀……没解析成功。
后来我把Tag96的流保存成文件,打算通过文件的方式去解析的时候,突然发现这个Tag96转成的字符串,看着有点眼熟啊,还是“8=”开头,这他喵的不就是STEP协议么,这他喵坑人啊,他给的文档也没说他套娃啊,说好的禁止套娃呢。
最终,把Tag96拉出来再跑一次解析STEP协议的代码再拉一个Tag96出来然后解析,然后就解析成功了,其实最初的方式其实是没错的,错无非是数据源给我挖了一个坑。
示例代码
先上大佬的代码吧,加了几行是个人都不需要的注释供参考
//从文件中导入模板,自己注意一下路径即可
InputStream templateSource = new FileInputStream("data/RDDFastTemplates-1.1.xml");
XMLMessageTemplateLoader templateLoader = new XMLMessageTemplateLoader();
templateLoader.setLoadTemplateIdFromAuxId(true);
//载入模板
templateLoader.load(templateSource);
System.out.println("the tamplate count is" + templateLoader.getTemplateRegistry().getTemplates().length);
//载入数据源
InputStream is = new FileInputStream("data/fastdata.bin");
MessageInputStream mis = new MessageInputStream(is);
//注册模板
mis.setTemplateRegistry(templateLoader.getTemplateRegistry());
Message md = null;
int iCount = 0;
//打开debug追踪开关,显示字段信息
mis.getContext().setTraceEnabled(true);
//循环解析,直到解析完
while((md = mis.readMessage()) != null)
{
System.out.println("the mesage template id is: " + md.getTemplate().getId());
}
我的代码,其实区别不大
//用糊涂工具类取文件,模板路径为源代码的:resources/template/template.xml
ClassPathResource classPathResource = new ClassPathResource("template/template.xml");
InputStream inputStream = classPathResource.getStream();
//一个模板文件可能包含多个模板,我这里只有1个,省事就直接搞了
MessageTemplate template = new XMLMessageTemplateLoader().load(inputStream)[0];
Context context = new Context();
context.registerTemplate(4001, template);
try {
//数据源byte[]
InputStream sbs = new ByteArrayInputStream(buff);
//解码器
FastDecoder fastDecoder = new FastDecoder(context, sbs);
//重置一下状态,理论上是没解析一条需要重置一次
//fastDecoder.reset();
//解码
Message msg111 = fastDecoder.readMessage();
log.info("解码的消息1:{}", msg111.getString(1));
} catch (Exception e) {
e.printStackTrace();
}