fix协议封装挑战-将消息字符串解析为实体

这个是真正的有挑战的,我的方法还是递归解析。

举个例子:

比如下面返回消息:

响应:
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_

这是一个35=8的消息,也就是ExecutionReportMsg

他的实体如下:

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-11-29
 */
public class ExecutionReportMsg extends BaseMsg {
	private Tag clOrdID=new Tag("11","String",false);
	private Tag cumQty=new Tag("14","Qty",true);
	private Tag execID=new Tag("17","String",true);
	private Tag execType=new Tag("150","char",true);
	private Tag leavesQty=new Tag("151","Qty",true);
	private Tag lotType=new Tag("1093","char",false);
	private Tag maxPriceLevels=new Tag("1090","int",false);
	private Tag parties=new PartiesTag(false);
	private Tag orderID=new Tag("37","String",true);
	private Tag orderQtyData=new OrderQtyDataTag(false);
	private Tag ordStatus=new Tag("39","char",true);
	private Tag ordType=new Tag("40","char",false);
	private Tag price=new Tag("44","Price",false);
	private Tag instrument=new InstrumentTag(true);
	private Tag side=new Tag("54","char",true);
	private Tag timeInForce=new Tag("59","char",false);
	private Tag transactTime=new Tag("60","UTCTimestamp",false);
	private Tag ordRejReason=new Tag("103","int",false);
	private Tag rejectText=new Tag("1328","String",false);
	private Tag lastPx=new Tag("31","Price",false);
	private Tag lastQty=new Tag("32","Qty",false);
	private Tag matchType=new Tag("574","String",false);
	private Tag trdMatchID=new Tag("880","String",false);
	private Tag execRefID=new Tag("19","String",false);
	private Tag execRestatementReason=new Tag("378","int",false);
	private Tag origClOrdID=new Tag("41","String",false);
	
	private Set<String> tagIdsSet=new HashSet<String>();
	public ExecutionReportMsg(){
		this.getHeadEntity().getMsgType().setTagValue("8");
		tagIdsSet.add("11");
		tagIdsSet.add("14");
		tagIdsSet.add("17");
		tagIdsSet.add("150");
		tagIdsSet.add("151");
		tagIdsSet.add("1093");
		tagIdsSet.add("1090");
		tagIdsSet.add("37");
		tagIdsSet.add("39");
		tagIdsSet.add("40");
		tagIdsSet.add("44");
		tagIdsSet.add("54");
		tagIdsSet.add("59");
		tagIdsSet.add("60");
		tagIdsSet.add("103");
		tagIdsSet.add("1328");
		tagIdsSet.add("31");
		tagIdsSet.add("32");
		tagIdsSet.add("574");
		tagIdsSet.add("880");
		tagIdsSet.add("19");
		tagIdsSet.add("378");
		tagIdsSet.add("41");
		this.bodyEntity.getBodyTagList().add(clOrdID);
		this.bodyEntity.getBodyTagList().add(cumQty);
		this.bodyEntity.getBodyTagList().add(execID);
		this.bodyEntity.getBodyTagList().add(execType);
		this.bodyEntity.getBodyTagList().add(leavesQty);
		this.bodyEntity.getBodyTagList().add(lotType);
		this.bodyEntity.getBodyTagList().add(maxPriceLevels);
		this.bodyEntity.getBodyTagList().add(parties);
		this.bodyEntity.getBodyTagList().add(orderID);
		this.bodyEntity.getBodyTagList().add(orderQtyData);
		this.bodyEntity.getBodyTagList().add(ordStatus);
		this.bodyEntity.getBodyTagList().add(ordType);
		this.bodyEntity.getBodyTagList().add(price);
		this.bodyEntity.getBodyTagList().add(instrument);
		this.bodyEntity.getBodyTagList().add(side);
		this.bodyEntity.getBodyTagList().add(timeInForce);
		this.bodyEntity.getBodyTagList().add(transactTime);
		this.bodyEntity.getBodyTagList().add(ordRejReason);
		this.bodyEntity.getBodyTagList().add(rejectText);
		this.bodyEntity.getBodyTagList().add(lastPx);
		this.bodyEntity.getBodyTagList().add(lastQty);
		this.bodyEntity.getBodyTagList().add(matchType);
		this.bodyEntity.getBodyTagList().add(trdMatchID);
		this.bodyEntity.getBodyTagList().add(execRefID);
		this.bodyEntity.getBodyTagList().add(execRestatementReason);
		this.bodyEntity.getBodyTagList().add(origClOrdID);
	}
	
	public void decodeBody() {
		Set<String> already=new HashSet<String>();
		String input=this.body;
		while(input.length()!=0){
			String firstTagId=input.substring(0, input.indexOf("="));
			if(firstTagId.equals("453")){
				input=this.getParties().decode(input, already);
			}else if(OrderQtyDataTag.tagIdsSet.contains(firstTagId)){
				input=this.orderQtyData.decode(input, already);
			}else if(InstrumentTag.tagIdsSet.contains(firstTagId)){
				input=this.instrument.decode(input, already);
			}else{
				List<Tag> tagList=this.bodyEntity.getBodyTagList();
				boolean exist=false;
				for(int j=0;j<tagList.size();j++){
					Tag tag=tagList.get(j);
					if(tag.getTagId().equals(firstTagId)){
						input=tag.decode(input, already);
						exist=true;
						break;
					}
				}
				if(!exist){
					throw new InValidDataException(firstTagId+"不在消息字段中");
				}
			}
			
		}
	}
	

	@Override
	public void validate() {
		this.headEntity.validate();
		List<Tag> bodyTagList=this.bodyEntity.getBodyTagList();
		for(int i=0;i<bodyTagList.size();i++){
			bodyTagList.get(i).validate();
		}
		this.tailerEntity.validate();
		if(execType.getTagValue()!=null){
			if(!MsgUtil.execType.contains(execType.getTagValue())){
				throw new InValidDataException("execType错误["+execType.getTagId()+"="+execType.getTagValue()+"]");
			}
		}
		if(lotType.getTagValue()!=null){
			if(!MsgUtil.lotType.contains(lotType.getTagValue())){
				throw new InValidDataException("lotType错误["+lotType.getTagId()+"="+lotType.getTagValue()+"]");
			}
		}
		if(ordStatus.getTagValue()!=null){
			if(!MsgUtil.ordStatus.contains(ordStatus.getTagValue())){
				throw new InValidDataException("ordStatus错误["+ordStatus.getTagId()+"="+ordStatus.getTagValue()+"]");
			}
		}
		if(ordType.getTagValue()!=null){
			if(!MsgUtil.ordType.contains(ordType.getTagValue())){
				throw new InValidDataException("ordType错误["+ordType.getTagId()+"="+ordType.getTagValue()+"]");
			}
		}
		if(side.getTagValue()!=null){
			if(!MsgUtil.side.contains(side.getTagValue())){
				throw new InValidDataException("side错误["+side.getTagId()+"="+side.getTagValue()+"]");
			}
		}
		if(timeInForce.getTagValue()!=null){
			if(!MsgUtil.timeInForce.contains(timeInForce.getTagValue())){
				throw new InValidDataException("timeInForce错误["+timeInForce.getTagId()+"="+timeInForce.getTagValue()+"]");
			}
		}
		if(ordRejReason.getTagValue()!=null){
			if(!((Integer.parseInt(ordRejReason.getTagValue())>=0&&Integer.parseInt(ordRejReason.getTagValue())<=19)||Integer.parseInt(ordRejReason.getTagValue())==99)){
				throw new InValidDataException("ordRejReason错误["+ordRejReason.getTagId()+"="+ordRejReason.getTagValue()+"]");
			}
		}
		if(matchType.getTagValue()!=null){
			if(!MsgUtil.matchType.contains(matchType.getTagValue())){
				throw new InValidDataException("matchType错误["+matchType.getTagId()+"="+matchType.getTagValue()+"]");
			}
		}
	}

	public Tag getClOrdID() {
		return clOrdID;
	}

	public void setClOrdID(Tag clOrdID) {
		this.clOrdID = clOrdID;
	}

	public Tag getCumQty() {
		return cumQty;
	}

	public void setCumQty(Tag cumQty) {
		this.cumQty = cumQty;
	}

	public Tag getExecID() {
		return execID;
	}

	public void setExecID(Tag execID) {
		this.execID = execID;
	}

	public Tag getExecType() {
		return execType;
	}

	public void setExecType(Tag execType) {
		this.execType = execType;
	}

	public Tag getLeavesQty() {
		return leavesQty;
	}

	public void setLeavesQty(Tag leavesQty) {
		this.leavesQty = leavesQty;
	}

	public Tag getLotType() {
		return lotType;
	}

	public void setLotType(Tag lotType) {
		this.lotType = lotType;
	}

	public Tag getMaxPriceLevels() {
		return maxPriceLevels;
	}

	public void setMaxPriceLevels(Tag maxPriceLevels) {
		this.maxPriceLevels = maxPriceLevels;
	}

	public Tag getParties() {
		return parties;
	}

	public void setParties(Tag parties) {
		this.parties = parties;
	}

	public Tag getOrderID() {
		return orderID;
	}

	public void setOrderID(Tag orderID) {
		this.orderID = orderID;
	}

	public Tag getOrderQtyData() {
		return orderQtyData;
	}

	public void setOrderQtyData(Tag orderQtyData) {
		this.orderQtyData = orderQtyData;
	}

	public Tag getOrdStatus() {
		return ordStatus;
	}

	public void setOrdStatus(Tag ordStatus) {
		this.ordStatus = ordStatus;
	}

	public Tag getOrdType() {
		return ordType;
	}

	public void setOrdType(Tag ordType) {
		this.ordType = ordType;
	}

	public Tag getPrice() {
		return price;
	}

	public void setPrice(Tag price) {
		this.price = price;
	}

	public Tag getInstrument() {
		return instrument;
	}

	public void setInstrument(Tag instrument) {
		this.instrument = instrument;
	}

	public Tag getSide() {
		return side;
	}

	public void setSide(Tag side) {
		this.side = side;
	}

	public Tag getTimeInForce() {
		return timeInForce;
	}

	public void setTimeInForce(Tag timeInForce) {
		this.timeInForce = timeInForce;
	}

	public Tag getTransactTime() {
		return transactTime;
	}

	public void setTransactTime(Tag transactTime) {
		this.transactTime = transactTime;
	}

	public Set<String> getTagIdsSet() {
		return tagIdsSet;
	}

	public void setTagIdsSet(Set<String> tagIdsSet) {
		this.tagIdsSet = tagIdsSet;
	}

	public Tag getOrdRejReason() {
		return ordRejReason;
	}

	public void setOrdRejReason(Tag ordRejReason) {
		this.ordRejReason = ordRejReason;
	}

	public Tag getRejectText() {
		return rejectText;
	}

	public void setRejectText(Tag rejectText) {
		this.rejectText = rejectText;
	}

	public Tag getLastPx() {
		return lastPx;
	}

	public void setLastPx(Tag lastPx) {
		this.lastPx = lastPx;
	}

	public Tag getLastQty() {
		return lastQty;
	}

	public void setLastQty(Tag lastQty) {
		this.lastQty = lastQty;
	}

	public Tag getMatchType() {
		return matchType;
	}

	public void setMatchType(Tag matchType) {
		this.matchType = matchType;
	}

	public Tag getTrdMatchID() {
		return trdMatchID;
	}

	public void setTrdMatchID(Tag trdMatchID) {
		this.trdMatchID = trdMatchID;
	}

	public Tag getExecRefID() {
		return execRefID;
	}

	public void setExecRefID(Tag execRefID) {
		this.execRefID = execRefID;
	}

	public Tag getExecRestatementReason() {
		return execRestatementReason;
	}

	public void setExecRestatementReason(Tag execRestatementReason) {
		this.execRestatementReason = execRestatementReason;
	}

	public Tag getOrigClOrdID() {
		return origClOrdID;
	}

	public void setOrigClOrdID(Tag origClOrdID) {
		this.origClOrdID = origClOrdID;
	}

}
CsFixProtocolDecoder类的指令:
baseMessage.setHead(msgArray[0]);
				baseMessage.setBody(msgArray[1]);
				baseMessage.setTailer(msgArray[2]);
				baseMessage.decode();
BaseMsg的方法:
public void decode(){
		decodeHead();
		decodeBody();
		decodeTailer();
	}

注意
ExecutionReportMsg 
类的decodeBody方法,依次将输入流解析,如果是组合Tag,会吧流传入组合tag依次依稀,值到遇到最简单的tag直接解析

Tag类的方法:

public String decode(String input,Set<String> already){
		String myItem=input.substring(0, input.indexOf(BaseMsg.SOH));
		String returnStr=input.substring(input.indexOf(BaseMsg.SOH)+1);
		String [] tagItems=myItem.split("=");
		if(tagItems.length!=2){
			throw new InValidDataException("消息格式错误");
		}
		if(already.contains(tagId)){
			throw new InValidDataException(tagId+"消息已被解析");
		}
		if(this.getTagId().equals(tagItems[0])){
			this.tagValue=tagItems[1];
			already.add(tagItems[0]);
			return returnStr;
		}else{
			throw new InValidDataException("解析错误["+tagId+"-"+tagItems[0]+"]");
		}
	}



你可能感兴趣的:(fix协议封装挑战-将消息字符串解析为实体)