如何将含FIX 4.4报文的原始字符串转换为对应类型的QuickFIX/J Message对象
结论
优先选择方案2,即调用quickfix.MessageUtils.parse()的实现,这也是QuickFIX/J官方推荐的标准写法。
两种方案对比
方案1的缺陷
- 重复解析报文:你先调用
new quickfix.Message(rawMessageString)解析一次报文取MsgType,后续又调用fromString再解析一次填充字段,平白多了一倍的解析开销,报文处理量较大时性能差异会非常明显。 - 容错性差:手动读取MsgType的逻辑没有做边界校验,如果报文不规范缺少MsgType字段、版本号不匹配,很容易出现空指针或解析异常,你需要额外补充大量异常处理逻辑才能满足生产可用性。
- 可维护性低:代码里硬编码了FIX.4.4版本号,后续如果要调整版本兼容,需要修改多处逻辑,容易出现疏漏。
方案2的优势
- 官方封装的成熟逻辑:
MessageUtils.parse()已经把「解析报文版本号、提取MsgType、通过工厂生成对应类型实例、调用fromString填充字段」这一整套逻辑都做了封装,你不需要重复造轮子,代码更简洁,出BUG的概率更低。 - 兼容性好:后续生产环境要引入DataDictionary时,直接把字典实例作为第二个参数传入
parse方法即可,现有逻辑几乎不需要改动。 - 异常处理更规范:官方方法已经处理了报文不合法、版本不支持、MsgType未知等各类边界场景,会抛出标准的QuickFIX/J异常,你只要统一捕获处理即可。
生产环境优化建议
- 不要每次解析都新建
DefaultMessageFactory实例,这个工厂是线程安全的,可以做成单例全局复用,避免不必要的对象创建开销。 - 生产环境必须传入正确的DataDictionary实例,否则解析时不会做字段合法性校验,也无法正确识别自定义字段、枚举值,很容易出现解析错误。
- DataDictionary也可以做成单例全局复用,避免每次加载字典文件的IO开销。
生产环境参考代码
// 全局单例初始化,服务启动时只加载一次 private static final DataDictionary FIX44_DICTIONARY = new DataDictionary("FIX44.xml"); private static final MessageFactory FIX44_MESSAGE_FACTORY = new DefaultMessageFactory(ApplVerID.FIX44); // 报文解析逻辑 public quickfix.Message parseFix44Message(String rawMessageString) throws InvalidMessage { return MessageUtils.parse(FIX44_MESSAGE_FACTORY, FIX44_DICTIONARY, rawMessageString); }
内容的提问来源于stack exchange,提问作者Felipe Windmoller
相关产品推荐
相关产品推荐

