消息实体如下:

 

package cs.test;

import java.text.SimpleDateFormat;
import java.util.Date;

import cs.mina.SeqenceNum;
import cs.mina.codec.msg.BaseMsg;
import cs.mina.codec.msg.DisclosureInstructionGrp;
import cs.mina.codec.msg.DisclosureInstructionGrpTag;
import cs.mina.codec.msg.InstrumentTag;
import cs.mina.codec.msg.NewOrderSingleMsg;
import cs.mina.codec.msg.OrderQtyDataTag;
import cs.mina.codec.msg.PartiesTag;
import cs.mina.codec.msg.Party;

/*
*@author(huangxiaoping)
*@date 2013-11-29
*/
public class TC_OM_04Test {
public static BaseMsg createMsg(){
NewOrderSingleMsg msg=new NewOrderSingleMsg();
msg.getHeadEntity().getMsgSeqNum().setTagValue(SeqenceNum.getSeqence()+"");
msg.getClOrdID().setTagValue("13");
msg.getParties().setTagValue("1");
Party party=new Party();
party.getPartyID().setTagValue("1122");
party.getPartyIDSource().setTagValue("D");
party.getPartyRole().setTagValue("1");
((PartiesTag)msg.getParties()).getChildren().add(party);
((InstrumentTag)msg.getInstrument()).getSecurityID().setTagValue("36");
((InstrumentTag)msg.getInstrument()).getSecurityIDSource().setTagValue("8");
((InstrumentTag)msg.getInstrument()).getSecurityExchange().setTagValue("XHKG");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSS");
msg.getTransactTime().setTagValue(sdf.format(new Date()));
msg.getSide().setTagValue("2");
msg.getOrdType().setTagValue("2");
msg.getPrice().setTagValue("30.05");
((OrderQtyDataTag)msg.getOrderQtyData()).getOrderQty().setTagValue("4000");
msg.getTimeInForce().setTagValue("0");
msg.getMaxPriceLevels().setTagValue("1");
msg.getExecInst().setTagValue("c x");

DisclosureInstructionGrp dis=new DisclosureInstructionGrp();
dis.getDisclosureType().setTagValue("100");
dis.getDisclosureInstruction().setTagValue("1");
((DisclosureInstructionGrpTag)msg.getDisclosureInstructionGrp()).setTagValue("1");
((DisclosureInstructionGrpTag)msg.getDisclosureInstructionGrp()).getChildren().add(dis);
return msg;

}
}

 

消息如下:

 

测试案例TC_OM_04
测试数据1
发送:
8=FIXT.1.1_9=206_35=D_49=CO99999901_56=HKEXCO_34=3_52=20131129-15:07:00.902_11=13_453=1_448=1122_447=D_452=1_18=c x_1090=1_48=36_22=8_207=XHKG_60=20131129-15:07:00.903_54=2_40=2_44=30.05_38=4000_59=0_1812=1_1813=100_1814=1_10=146_
响应:
8=FIXT.1.1_9=239_35=8_49=HKEXCO_56=CO99999901_34=3_52=20131129-07:07:01.327_1128=9_11=13_14=0_17=20701315_150=0_151=4000_1093=2_1090=1_453=1_448=1122_447=D_452=1_37=30701209_38=4000_39=0_40=2_44=30.05_207=XHKG_48=36_22=8_54=2_59=0_60=20131129-07:07:01.317_10=027_

说明:

 

消息的构造很简单,就是javabean,关键是如何把这个javabean解析为消息字符串。

解析原理如下:

package cs.mina.codec.msg; import java.util.HashSet; import java.util.List; import java.util.Set; import cs.mina.exception.InValidDataException; /* *@author(huangxiaoping) *@date 2013-10-24 */ public abstract class BaseMsg { public static final String SOH = "\u0001"; protected String head; protected String body; protected String tailer; protected Head headEntity=new Head(); protected Body bodyEntity=new Body(); protected Tailer tailerEntity=new Tailer(); public abstract void validate(); public String encode(){ String result=""; List<Tag> headTagList=this.headEntity.getHeadTagList(); for(int i=0;i<headTagList.size();i++){ Tag headTag=headTagList.get(i); result+=headTag.encode(); } List<Tag> bodyTagList=this.bodyEntity.getBodyTagList(); for(int i=0;i<bodyTagList.size();i++){ Tag bodyTag=bodyTagList.get(i); result+=bodyTag.encode(); } List<Tag> tailerTagList=this.tailerEntity.getTailerTagList(); for(int i=0;i<tailerTagList.size();i++){ Tag tailerTag=tailerTagList.get(i); result+=tailerTag.encode(); } return result; } public void decode(){ decodeHead(); decodeBody(); decodeTailer(); } public abstract void decodeBody(); public void decodeHead(){ Set<String> already=new HashSet<String>(); String[] headItems=this.head.split(SOH); for(int i=0;i<headItems.length;i++){ String headItem=headItems[i]; String[] headTagItems=headItem.split("="); if(headTagItems.length!=2){ throw new InValidDataException("消息格式错误"); } if(already.contains(headTagItems[0])){ throw new InValidDataException("消息格式错误"); } already.add(headTagItems[0]); if(headTagItems[0].equals("627")){ int skip=decodeGroup627(); i=i+skip-1; }else{ List<Tag> headTags=this.headEntity.getHeadTagList(); for(int j=0;j<headTags.size();j++){ Tag headTag=headTags.get(j); if(headTag.getTagId().equals(headTagItems[0])){ headTag.setTagValue(headTagItems[1]); } } } } } private int decodeGroup627(){ int index=head.indexOf("627="); String rest=head.substring(index); String[]tagItems=rest.split(BaseMsg.SOH); String[] numTagItems=tagItems[0].split("="); if(numTagItems.length!=2){ throw new InValidDataException("消息格式错误"); } if(!"627".equals(numTagItems[0])){ throw new InValidDataException("消息格式错误"); } int num=Integer.parseInt(numTagItems[1]); int count=1; int whileCount=0; ((HopGrpTag)this.headEntity.getHopGrpTag()).setTagValue(num+""); boolean end=false; for(int i=0;i<num;i++){ if(end){ if(i!=num){ throw new InValidDataException("消息格式错误"); }else{ break; } } HopGrp hopGrp=new HopGrp(); ((HopGrpTag)this.getHeadEntity().getHopGrpTag()).getChildren().add(hopGrp); while(true){ if(whileCount>=3){ whileCount=0; break; } if(tagItems.length==count){ break; } String[] tagIt=tagItems[count].split("="); if(tagIt.length!=2){ throw new InValidDataException("消息格式错误"); } if(whileCount==0){ if(!HopGrpTag.first.equals(tagIt[0])){ throw new InValidDataException("消息格式错误"); } } if(HopGrp.tagIdsSet.contains(tagIt[0])){ List<Tag> tagList=hopGrp.getTagList(); for(int j=0;j<tagList.size();j++){ Tag groupTag=tagList.get(j); if(groupTag.getTagId().equals(tagIt[0])){ groupTag.setTagValue(tagIt[1]); break; } } if(tagItems.length>count+1){ String[] nextTagIt=tagItems[count+1].split("="); if(nextTagIt.length!=2){ throw new InValidDataException("消息格式错误"); } if(HopGrpTag.first.equals(nextTagIt[0])){ whileCount=0; count++; break; } } count++; whileCount++; }else{ end=true; break; } } } return count; } public void decodeTailer(){ Set<String> already=new HashSet<String>(); String[] tailerItems=this.tailer.split(SOH); for(int i=0;i<tailerItems.length;i++){ String tailerItem=tailerItems[i]; String[] tailerTagItems=tailerItem.split("="); if(tailerTagItems.length!=2){ throw new InValidDataException("消息格式错误"); } if(already.contains(tailerTagItems[0])){ throw new InValidDataException("消息格式错误"); } already.add(tailerTagItems[0]); List<Tag> tailerTags=this.tailerEntity.getTailerTagList(); for(int j=0;j<tailerTags.size();j++){ Tag tailerTag=tailerTags.get(j); if(tailerTag.getTagId().equals(tailerTagItems[0])){ tailerTag.setTagValue(tailerTagItems[1]); } } } } public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getTailer() { return tailer; } public void setTailer(String tailer) { this.tailer = tailer; } public Head getHeadEntity() { return headEntity; } public void setHeadEntity(Head headEntity) { this.headEntity = headEntity; } public Body getBodyEntity() { return bodyEntity; } public void setBodyEntity(Body bodyEntity) { this.bodyEntity = bodyEntity; } public Tailer getTailerEntity() { return tailerEntity; } public void setTailerEntity(Tailer tailerEntity) { this.tailerEntity = tailerEntity; } }

消息头和消息尾是共用的,用通用的方法解析就可以了。关键是消息体,每个消息的消息体不一样,但是我们还是可以用递归的方式解析。

注意encode 方法