`
thb143
  • 浏览: 8444 次
文章分类
社区版块
存档分类
最新评论

mina自定义编码解码器

阅读更多
公司正在做一个C/S的东西,其中用到了Mina框架,故对其中自定义编码解码器做了一些研究!
package net.xml;

import java.nio.charset.Charset;

import org.apache.log4j.Logger;

public class InfoXml {
	private static Logger logger = Logger.getLogger(InfoXml.class);
//	private short tag;
	private String xml;
	
	public short getTag(){
		return (short)0x0001;
	}
	
	public int getLen(Charset charset){
		int len = 0;
		try {
			len += xml.getBytes(charset).length;
		} catch (Exception e) {
			logger.error("数据错误", e);
			e.printStackTrace();
		}
		return len;
	}
	
//	public short getTag() {
//		return tag;
//	}
//	public void setTag(short tag) {
//		this.tag = tag;
//	}
	public String getXml() {
		return xml;
	}
	public void setXml(String xml) {
		this.xml = xml;
	}
	
}


重写解码编码方法
package net.xml;

import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageEncoder;

public class InfoMessageCodecFactory extends DemuxingProtocolCodecFactory{
	private MessageDecoder decoder;
	private MessageEncoder<InfoXml> encoder;
	
	public InfoMessageCodecFactory(MessageDecoder decoder,MessageEncoder<InfoXml> encoder){
		this.decoder = decoder;
		this.encoder = encoder;
		addMessageDecoder(this.decoder);
		addMessageEncoder(InfoXml.class, this.encoder);
	}
}


package net.xml;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

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.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;

public class InfoMessageDecoder implements MessageDecoder{
	private static Logger logger = Logger.getLogger(InfoMessageDecoder.class);
	private Charset charset;
	public InfoMessageDecoder(Charset charset){
		this.charset = charset;
	}

	@Override
	public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
		if(in.remaining() < 6){
			return MessageDecoderResult.NEED_DATA;
		}
		short tag = in.getShort();
		if (tag == (short)0x0001 || tag == (short)0x8001) {
			logger.info("请求标识符:" + tag);
		} else {
			logger.error("未知的解码类型....");
			return MessageDecoderResult.NOT_OK;
		}
		int len = in.getInt();
		if (in.remaining() < len) {
			return MessageDecoderResult.NEED_DATA;
		}
		return MessageDecoderResult.OK;
	}

	@Override
	public MessageDecoderResult decode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput out) throws Exception {
		logger.info("解码: "+in.toString());
		CharsetDecoder decoder = charset.newDecoder();
		short tag = in.getShort();
		int len = in.getInt();
		byte[] temp = new byte[len];
		in.get(temp);
		
		IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
		buf.put(temp);
		buf.flip();
		
		InfoXml ix = new InfoXml();
		String xml = buf.getString(len, decoder);

		ix.setXml(xml);
		out.write(ix);
		return MessageDecoderResult.OK;
	}

	@Override
	public void finishDecode(IoSession session, ProtocolDecoderOutput out)
			throws Exception {
	}

}


package net.xml;

import java.nio.charset.Charset;

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.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.demux.MessageEncoder;

public class InfoMessageEncoder implements MessageEncoder<InfoXml>{
	private static Logger logger = Logger.getLogger(InfoMessageEncoder.class);
	private Charset charset;
	
	public InfoMessageEncoder(Charset charset){
		this.charset = charset;
	}
	
	@Override
	public void encode(IoSession session, InfoXml ix, ProtocolEncoderOutput out)
			throws Exception {
		IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
		buf.putShort(ix.getTag());
		buf.putInt(ix.getLen(charset));
		buf.putString(ix.getXml(), charset.newEncoder());
		buf.flip();
		logger.info("编码" + buf.toString());
		out.write(buf);
	}

}


业务逻辑类
package net.xml;

import java.util.Iterator;

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


public class InfoServerHandler extends IoHandlerAdapter{
	public static Logger logger = Logger.getLogger(InfoServerHandler.class);
    String commandText = null;
    String usernameText = null;
    String passwordText = null;

	@Override
	public void sessionCreated(IoSession session) throws Exception {
		logger.info("服务端与客户端创建连接...");
	}

	@Override
	public void sessionOpened(IoSession session) throws Exception {
		logger.info("服务端与客户端连接打开...");
	}
	
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		if (message instanceof InfoXml) {
			InfoXml ix = (InfoXml)message;
			String xml = ix.getXml();
			System.out.println("请求数据: "+xml);
			
			Document doc = DocumentHelper.parseText(xml);
			Element rootElt = doc.getRootElement(); // 获取根节点
	        System.out.println("根节点:" + rootElt.getName()); // 拿到根节点的名称
	        Iterator it = rootElt.elementIterator();
	        while(it.hasNext()){
	        	it.next();
	        	commandText = rootElt.elementTextTrim("command"); 
	        	usernameText = rootElt.elementTextTrim("username");
	        	passwordText = rootElt.elementTextTrim("password");
	        }
	        StringBuffer sb = new StringBuffer(1000);
	        sb.append("<response>");
	        sb.append("<success>");
	        if ("login".equals(commandText)) {
	        	if ("abc".equals(usernameText) && "123".equals(passwordText)) {
	        		sb.append("true");
	        	} else {
	        		sb.append("false");
	        	}
	        }
	        sb.append("</success>");
	        sb.append("</response>");
	        
	        InfoXml res = new InfoXml();
//	        res.setTag((short)0x8001);
	        res.setXml(sb.toString());
	        
	        session.write(res);
		} else {
			logger.info("未知请求!");
		}
	}
		
	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		session.close();
		logger.info("服务端发送信息成功...");
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {

	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status)
			throws Exception {
		logger.info("服务端进入空闲状态...");
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		logger.error("服务端发送异常...", cause);
	}
}


package net.xml;

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class InfoClientHandler extends IoHandlerAdapter{
	private static Logger logger = Logger.getLogger(InfoClientHandler.class);
	
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		InfoXml ix = (InfoXml)message;
		String xml = ix.getXml();
		System.out.println("响应数据:"+xml);
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		logger.error("客户端发生异常...", cause);
	}
}


这个自定义编码解码,报头传递标识符和读取长度,然后是真实数据区,采用xml字符串传递!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics