Skip to content

QFJ Program Tips

Baoying Wang edited this page Mar 9, 2018 · 3 revisions

be defensive - always set ValidateFieldsOutOfOrder and ValidateUnorderedGroupFields to N

Hard to promise the order because it will make enhancement very difficult. Set it to N will protect yourself

ValidateFieldsOutOfOrder If set to N, fields that are out of order (i.e. body fields in the header, or header fields in the body) will not be rejected. Useful for connecting to systems which do not properly order fields. Default :Y

ValidateUnorderedGroupFields Session validation setting for enabling whether field ordering is * validated. Values are "Y" or "N". Default is "Y".

see: https://www.quickfixj.org/usermanual/1.6.4//usage/configuration.html

be defensive - always check isSetField whether before get value from a field

Otherwise, the method will throw FieldNotFound exception on empty value. For some optional fields, it is possible that the field is NOT provided. You cannot use the common way - get value and check null/empty. I think this is a bad QFJ design.

I would suggest to write a wrapper to get value e.g.

class QFJFieldGetter{

    public static String getString(FieldMap msgOrGroup, int tag){
        if(msgOrGroup.isSetField, tag){
            return msgOrGroup.getString(tag);
        }else{
            return null;
        }
    }
}

note: for the fields that you 100% confident with value, you can get directly. note: you should always catch exception while processing a message. If there is any problem on current message processing, you could skip it and process next.

how to parse a String into Message (not request to tell SessionID)

You need it only for test.


import quickfix.DataDictionary;
import quickfix.DefaultMessageFactory;
import quickfix.Message;
import quickfix.MessageFactory;

public class StringMessageParseExample {

    public static void main(String[] args) throws Exception{
        MessageFactory messageFactory = new DefaultMessageFactory();
        DataDictionary dataDictionary = new DataDictionary("FIX50SP1.xml");        
        dataDictionary.setCheckUnorderedGroupFields(false);
        dataDictionary.setCheckFieldsOutOfOrder(false);


        String messageString = "8=FIXT.1.1%9=215%35=8%34=2%49=BaoyingMatchingCompID%52=20171229-02:54:07.319%56=BACKGROUND_FIX1514516040861_0%11=BACKGROUND_FIX1514516040861_01514516047312_1%14=0%17=2437234712035%37=1514515971769_42%39=0%54=2%55=USDJPY%150=0%151=2%10=075%";
        messageString = messageString.replace('%', (char)0x01);
        Message qfjMsg = quickfix.MessageUtils.parse(messageFactory,dataDictionary,messageString );

        dataDictionary.validate(qfjMsg);

        System.out.println(qfjMsg.toString());
    }
}


the direction location could be classpath, or filesystem path

e.g. AppDataDictionary=dictionary/FIX50SP1.xml The source code will try to search on different type(location, classloader, url, etc). Soure code:

    private void DataDictionary:read(String location) throws ConfigError {
        final InputStream inputStream = FileUtil.open(getClass(), location, URL, FILESYSTEM,
                CONTEXT_RESOURCE, CLASSLOADER_RESOURCE);  

   public static InputStream FileUtil::open  (Class<?> clazz, String name, Location... locations)

how to close a session ( by session.disconnect)

Session.disconnect(reason:String, logError:boolean)

Clone this wiki locally