quickfix.Message 无法转换为 quickfix。fix50sp2.Message

quickfix.Message cannot be cast to quickfix.fix50sp2.Message

我使用的是最新的 quickfix 版本 1.6.0。我已经有针对 1.5.3 编写的代码,我想做的是将其升级到 1.6.0

我遇到的问题是当我使用 crack(msg,sessionID) 方法时它抛出 quickfix.Message cannot be cast to quickfix.fix50sp2.Message 错误。我正在从 verifix 发送正确的 FIX50SP2 MarketDataSnapshotFullRefresh 消息。异常的摘录如下

java.lang.ClassCastException: quickfix.Message cannot be cast to quickfix.fix50sp2.Message at quickfix.fix50sp2.MessageCracker.crack(MessageCracker.java:1555) at com.****.fixserver.FixMessageListener.fromApp(FixMessageListener.java:162) at quickfix.Session.fromCallback(Session.java:1731) at quickfix.Session.verify(Session.java:1682)

如何将传入的消息破解为正确的 SP2 消息?

有一个 crack50() 方法,但它需要一个 SP2 消息,它在 fromApp 回调中不可用。

当开始字符串为 FIXT.1.1 时,quickfix 会将消息视为带有 DefaultMessageFactory 的 FIX50。所以会自动生成FIX.5.0信息。

解决方法是编写您自己的自定义消息工厂以在传输为 FIXT.1.1 时生成 SP2 消息。这是我的做法。

编写实现 quickfix.MessageFactory 接口的自定义消息工厂。您可以复制 DefaultMessageFactory 代码并更改 create() 方法,如下所示。

 public Message create(String beginString, String msgType) {
    MessageFactory messageFactory = messageFactories.get(beginString);
    if (beginString.equals(BEGINSTRING_FIXT11)) {
        // The default message factory assumes that only FIX 5.0 will be
        // used with FIXT 1.1 sessions. A more flexible approach will require
        // an extension to the QF JNI API. Until then, you will need a custom
        // message factory if you want to use application messages prior to
        // FIX 5.0 with a FIXT 1.1 session.
        //
        // TODO: how do we support 50/50SP1/50SP2 concurrently?
        //
        // If you need to determine admin message category based on a data
        // dictionary, then use a custom message factory and don't use the
        // static method used below.
        if (!MessageUtils.isAdminMessage(msgType)) {
            messageFactory = messageFactories.get(FIX50SP2);
        }
    }

    if (messageFactory != null) {
        return messageFactory.create(beginString, msgType);
    }

    Message message = new Message();
    message.getHeader().setString(MsgType.FIELD, msgType);

    return message;
}