协议编解码器是在使用Mina 的时候最需要关注的对象,因为网络传输的数据都是二进制数据(byte),而在程序中面向的是JAVA 对象,这就需要在发送数据时将JAVA 对象编码二进制数据,接收数据时将二进制数据解码为JAVA 对象。
编解码器同样是以过滤器的形式安插在过滤器链上,如下所示:
// 设置过滤器(使用Mina提供的文本换行符编解码器)
acceptor.getFilterChain().addLast(
"codec",
newProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"),
LineDelimiter.WINDOWS.getValue(),
LineDelimiter.WINDOWS.getValue())));
协议编解码器是通过ProtocolCodecFilter过滤器构造的,看它的构造方法,它需要一个ProtocolCodecFactory对象:
publicProtocolCodecFilter(ProtocolCodecFactory factory) {
if (factory == null){
throw newNullPointerException("factory");
}
this.factory =factory;
}
ProtocolCodecFactory接口非常直接,通过ProtocolEncoder和
ProtocolDecoder对象来构建!
public interfaceProtocolCodecFactory {
/**
* Returns a new (orreusable) instance of {@link ProtocolEncoder} which
* encodes message objectsinto binary or protocol-specific data.
*/
ProtocolEncodergetEncoder(IoSession session) throws Exception;
/**
* Returns a new (orreusable) instance of {@link ProtocolDecoder} which
* decodes binary orprotocol-specific data into message objects.
*/
ProtocolDecodergetDecoder(IoSession session) throws Exception;
}
ProtocolEncoder和ProtocolDecoder接口是Mina负责编码和解码的顶级接口!
编码和解码的前提就是协议的制定:比如上面我们使用的Mina自带的根据文本换行符解码的TextLineCodecFactory(),如果遇到文本换行符就开始编解码!
package lcl.mina.demo2;
import java.nio.charset.Charset;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
import lcl.mina.demo2.LCLTextLineCodecDecoder;
import lcl.mina.demo2.LCLTextLineCodecEncoder;
public class LCLTextLineCodecFactory implements ProtocolCodecFactory {
private Charset charset; // 编码格式
private String delimiter; // 文本分隔符
public LCLTextLineCodecFactory(Charset charset, String delimiter) {
this.charset = charset;
this.delimiter = delimiter;
}
//读取信息执行
public ProtocolDecoder getDecoder(IoSession session) throws Exception {
return new LCLTextLineCodecDecoder(charset, delimiter);
}
//发送编写信息执行
public ProtocolEncoder getEncoder(IoSession session) throws Exception {
return new LCLTextLineCodecEncoder(charset, delimiter);
}
}
package lcl.mina.demo2;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;