废话

还是那句话,网上搜得到的文档比和尚的头发还少,直接啃源码吧,啃了半天,终于啃到了一个类: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();
        }