java mina FundTradeProtocolDecoder

来源:互联网 发布:java错误无法加载主类 编辑:程序博客网 时间:2024/06/05 05:50
package com.pingan.emall.biz.communication.handler;




import com.pingan.emall.dto.MidResponseDTO;
import com.pingan.emall.util.StringUtil;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;




/**
 * 证券MID通讯返回解码器, 接收MID返回报文数据, 解析为基金频道对应的MIDResponseDTO对象
 * 并写到FilterChain中交由下一个filter处理。
 * 
 * doDecode方法复写了CumulativeProtocolDecoder中的abstract 方法, 用于处理网络断包,
 * 当返回的IoBuffer中包含的bytes不足 , 将IoBuffer指针复位并返回通知父方法,  父方法会
 * 根据返回结果决定是否将当前IoBuffer拼接到缓冲区中。
 * 
 * @author LICHAO844
 *
 */
public class FundTradeProtocolDecoder extends CumulativeProtocolDecoder {


private static Logger LOG = Logger.getLogger(FundTradeProtocolDecoder.class);
// length of response head length description string
private final static int RESPONSE_HEAD_LENGTH = 4;


private final static String SOH = "|";


private Charset charset;


public FundTradeProtocolDecoder(Charset charset) {
this.charset = charset == null ? Charset.defaultCharset() : charset;
}


@Override
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
// Mark current position, if buffer is not enough, reset buffer.
in.mark();   
// Get header length
if (in.remaining() < RESPONSE_HEAD_LENGTH) {
return false;
}
byte[] headLengthBytes = new byte[RESPONSE_HEAD_LENGTH];
in.get(headLengthBytes);
String headLengthStr = new String(headLengthBytes);
int headLength = Integer.parseInt(headLengthStr);


// Get the left data in header
if (in.remaining() < headLength - RESPONSE_HEAD_LENGTH) {
in.reset();
return false;
}
byte[] headBuffBytes = new byte[headLength - RESPONSE_HEAD_LENGTH];
in.get(headBuffBytes);
// Get header package
String headPackage = headLengthStr + new String(headBuffBytes, charset);


// Get body length
String[] headArray = StringUtil.split(headPackage, SOH);
int bodyLength = Integer.parseInt(headArray[1]);

// Get body package
if (in.remaining() < bodyLength) {
in.reset();
return false;
}
byte[] bodyBuffBytes = new byte[bodyLength];
in.get(bodyBuffBytes);
String bodyPackage = new String(bodyBuffBytes, charset);
out.write(parseResponsePackage(headPackage, bodyPackage));

if (LOG.isInfoEnabled()) {
String functionId = headArray[9];
String markedLog = FundTradeLogger.getMarkedInLog(functionId, headPackage + bodyPackage, session);
LOG.info(markedLog);
}

return true;
}

private MidResponseDTO parseResponsePackage(String headPackage, String bodyPackage) {
MidResponseDTO response = new MidResponseDTO();

// parse header package
String[] headArray = StringUtil.split(headPackage, SOH);
response.setResponseCode(Integer.parseInt(headArray[4]));
response.setResponseMessage(headArray[5]);
response.setHasNextPackage(Integer.parseInt(headArray[6]));


// parse body package
int fieldNum = Integer.parseInt(headArray[7]);
int rowNum = Integer.parseInt(headArray[8]);


if (rowNum > 0) {
List<Map<String, String>> resultList = new ArrayList<Map<String, String>>(rowNum);
String[] bodyArray = StringUtil.split(bodyPackage, SOH);


for (int k = 1; k <= rowNum; k++) {
Map<String, String> dataRow = new HashMap<String, String>(fieldNum);
int step = fieldNum * k;
for (int i = 0; i <= fieldNum - 1; i++) {
dataRow.put(bodyArray[i], bodyArray[i + step]);
}
resultList.add(dataRow);
}
response.setResultList(resultList);
}

return response;
}
}
0 0
原创粉丝点击