Apache Mina自定义编解码案例

Mina中已经自带的编解码类:

TextLineCodecFactory:基于文本的,根据回车换行来断点传输数据

ProtocolCodecFactory:自定义协议的编解码数据传输

ObjectSerializationCodecFactory:对象序列化传输

DemuxingProtocolCodecFactory:复用传输


自定义通信协议:

FlightSearch 1.0 \n
startcity:BJS \n
endcity:PEK \n
flightway:1 \n
date:2011-08-10 \n


Domain对象

package domain;

/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class Flight {
	public String startCity;
	public String endCity;
	public String flightway;
	public String date;
	public String fromDate;
	public String subclass1;
	public String flight1;
	
	/**
	 * 返回出发城市
	 * @return
	 */
	public String getStartCity() {
		return startCity;
	}
	public void setStartCity(String startCity) {
		this.startCity = startCity;
	}
	/**
	 * 返回到达城市
	 * @return
	 */
	public String getEndCity() {
		return endCity;
	}
	public void setEndCity(String endCity) {
		this.endCity = endCity;
	}
	/**
	 * 返回行程类型
	 * @return
	 */
	public String getFlightway() {
		return flightway;
	}
	public void setFlightway(String flightway) {
		this.flightway = flightway;
	}
	/**
	 * 返回出发日期
	 * @return
	 */
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	@Override
	public String toString() {
		return "Flight [startCity=" + startCity + ", endCity=" + endCity + ", flightway=" + flightway + ", date="
				+ date + "]";
	}
	/**
	 * 返回往返日期
	 * @return
	 */
	public String getFromDate() {
		return fromDate;
	}
	public void setFromDate(String fromDate) {
		this.fromDate = fromDate;
	}
	public String getFlight1() {
		return flight1;
	}
	public void setFlight1(String flight1) {
		this.flight1 = flight1;
	}
	public String getSubclass1() {
		return subclass1;
	}
	public void setSubclass1(String subclass1) {
		this.subclass1 = subclass1;
	}
}

服务器端编码

package server;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class FlightEncoder extends ProtocolEncoderAdapter {
	private final Charset charset = Charset.forName("UTF-8");
	/* 
	 * 服务器端编码无需处理,直接将接收到的数据向下传递
	 */
	@Override
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
		IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
		
		CharsetEncoder ce = charset.newEncoder();
		
		buf.putString((String)message, ce);
		
		buf.flip();
		
		out.write(buf);
	}

}

重点是服务器端解码

package server;

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

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

import domain.Flight;

/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class FlightDecoder extends CumulativeProtocolDecoder {

	@Override
	protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
		CharsetDecoder cd = Charset.forName("UTF-8").newDecoder();
		
		int ColumnNumber = 0;
		String status="",startCity="",endCity="",flightway="",date="";
		
		int TextLineNumber = 1;
		
		Flight flight = new Flight();

		/**
		 * FlightSearch 1.0 \n
		 * startcity:BJS \n
		 * endcity:PEK \n
		 * flightway:1 \n
		 * date:2011-08-10 \n
		 */
		while(in.hasRemaining()){
			byte b = in.get();
			buf.put(b);
			if(b == 10 && TextLineNumber <= 5){
				ColumnNumber++;
				if(TextLineNumber == 1){
					buf.flip();
					status = buf.getString(ColumnNumber, cd);
				}
				
				if(TextLineNumber == 2){
					buf.flip();
					startCity = buf.getString(ColumnNumber, cd).split(":")[1];
					startCity = startCity.substring(0, startCity.length()-1);
					flight.setStartCity(startCity);
				}
				
				if(TextLineNumber == 3){
					buf.flip();
					endCity = buf.getString(ColumnNumber, cd).split(":")[1];
					endCity = endCity.substring(0, endCity.length()-1);
					flight.setEndCity(endCity);
				}
				
				if(TextLineNumber == 4){
					buf.flip();
					flightway = buf.getString(ColumnNumber, cd).split(":")[1];
					flightway = flightway.substring(0, flightway.length()-1);
					flight.setFlightway(flightway);
				}
				
				if(TextLineNumber == 5){
					buf.flip();
					date = buf.getString(ColumnNumber, cd).split(":")[1];
					date = date.substring(0, date.length()-1);
					flight.setDate(date);
					break;
				}
				
				ColumnNumber = 0;
				buf.clear();
				TextLineNumber++;
			}else{
				ColumnNumber++;
			}
		}
		out.write(flight);
		return false;
	}

}

服务器端编解码工厂

package server;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;

/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class FlightCodecFactory implements ProtocolCodecFactory {
	private final ProtocolEncoder encoder = new FlightEncoder();
	private final ProtocolDecoder decoder = new FlightDecoder();

	@Override
	public ProtocolDecoder getDecoder(IoSession session) throws Exception {
		return decoder;
	}

	@Override
	public ProtocolEncoder getEncoder(IoSession session) throws Exception {
		return encoder;
	}

}



下面是客户端的编解码

重点是编码,需要将数据组装成协议格式,发送给服务器

package client;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import domain.Flight;


/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class FlightClientEncoder extends ProtocolEncoderAdapter {
	private final Charset charset;
	
	public FlightClientEncoder(){
		this.charset = Charset.forName("UTF-8");
	}

	@Override
	public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
		Flight flight = (Flight)message;
		
		IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
		
		CharsetEncoder ce = charset.newEncoder();
		
		buf.putString("Flight Search 1.0" + '\n', ce);
		
		buf.putString("startcty:" + flight.getStartCity() + '\n', ce);
		
		buf.putString("endcity:" + flight.getEndCity() + '\n', ce);
		
		buf.putString("flightway:" + flight.getFlightway() + '\n', ce);
		
		buf.putString("date:" + flight.getDate() + '\n', ce);
		
		buf.flip();
		
		out.write(buf);
	}

}


解码无需特殊处理,接收完数据直接向下传递

package client;

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

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;

/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class FlightClientDecoder extends CumulativeProtocolDecoder {

	/* (non-Javadoc)
	 * @see org.apache.mina.filter.codec.ProtocolDecoder#decode(org.apache.mina.core.session.IoSession, org.apache.mina.core.buffer.IoBuffer, org.apache.mina.filter.codec.ProtocolDecoderOutput)
	 */
	@Override
	protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		CharsetDecoder cd = Charset.forName("UTF-8").newDecoder();
		IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);
		
		while(in.hasRemaining()){
			buf.put(in.get());
		}
		buf.flip();
		out.write(buf.getString(cd));
		return false;
	}

}

客户端编解码工厂

package client;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;

/**
 * @function : 
 * @author   :jy
 * @company  :万里网
 * @date     :2011-8-7
 */
public class FlightClientCodecFactory implements ProtocolCodecFactory {
	private final ProtocolEncoder encoder = new FlightClientEncoder();
	private final ProtocolDecoder decoder = new FlightClientDecoder();
	
	/* (non-Javadoc)
	 * @see org.apache.mina.filter.codec.ProtocolCodecFactory#getDecoder(org.apache.mina.core.session.IoSession)
	 */
	@Override
	public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
		return decoder;
	}

	/* (non-Javadoc)
	 * @see org.apache.mina.filter.codec.ProtocolCodecFactory#getEncoder(org.apache.mina.core.session.IoSession)
	 */
	@Override
	public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
		return encoder;
	}

}


你可能感兴趣的:(JAVA)