好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Mina框架Filters

Mina框架Filters

Mina框架研究(3)

 

Filters

IoFilter  是MINA框架中一个核心的部分,如下图,对间于IoService和IoHandle之间,用于过滤所有的I/O事件和请求,其扮演的角色就像J2EE中的Servlet。

MINA提供不少现成的过滤器:

1、LoggingFilter  :日志过滤器,用于记录所有的事件和请求日志.

2、 ProtocolCodecFilter:规约解析过滤器,用来将所有收到的ByteBuffer内容转换为POJO消息(对象),实现往来报文的编码和解码;

3、 CompressionFilter:压缩过滤器;

4、SSLFilter

ProtocolCodecFilter

相对比较常用的是ProtocolCodecFilter,下面主要介绍一下ProtocolCodecFilter的使用:

还是以官方帮助文档中例子来说明( http://mina.apache.org/chapter-11-codec-filter.html )

这是一个图片服务器程序,请求图片的下行报文格式:

请求图片的宽度 
height: 请求图片的高度 
numchars: 生成的字节个数

服务端返回两张图片:

length1: 图片1的大小 
image1: 图片1(PNG格式) 
length2: 图片2的大小

image2: 图片2(PNG格式)

现在如果想通过MINA框架来实现基于这一简单规约的编解码通信功能,应该如何做呢?

    1:   public   class  ImageServer {
    2:       public   static   final   int  PORT = 33789;
    3:   
    4:       public   static   void  main(String[] args)  throws  IOException {
    5:          ImageServerIoHandler handler =  new  ImageServerIoHandler();
    6:          NioSocketAcceptor acceptor =  new  NioSocketAcceptor();
    7:          acceptor.getFilterChain().addLast( "protocol" ,  new  ProtocolCodecFilter( new  ImageCodecFactory(false)));
    8:          acceptor.setLocalAddress( new  InetSocketAddress(PORT));
    9:          acceptor.setHandler(handler);
   10:          acceptor.bind();
   11:          System.out.println( "server is listenig at port "  + PORT);
   12:      }
   13:  }

这里先来看和Filter有关的部分:

acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new ImageCodecFactory(false)));
在acceptor的Filter链中加入我们自己的过滤器,一个ProtocolCodecFilter的实现,这里的ImageCodecFactory又是什么呢?

    1:   public   class  ImageCodecFactory  implements  ProtocolCodecFactory {
    2:       private  ProtocolEncoder encoder;
    3:       private  ProtocolDecoder decoder;
    4:   
    5:       public  ImageCodecFactory( boolean  client) {
    6:           if  (client) {
    7:              encoder =  new  ImageRequestEncoder();
    8:              decoder =  new  ImageResponseDecoder();
    9:          }  else  {
   10:              encoder =  new  ImageResponseEncoder();
   11:              decoder =  new  ImageRequestDecoder();
   12:          }
   13:      }
   14:   
   15:       public  ProtocolEncoder getEncoder(IoSession ioSession)  throws  Exception {
   16:           return  encoder;
   17:      }
   18:   
   19:       public  ProtocolDecoder getDecoder(IoSession ioSession)  throws  Exception {
   20:           return  decoder;
   21:      }
   22:  }

ImageCodecFactory是对接口ProtocolCodecFactory 的实现,是用来构建Filter的。ProtocolCodecFactory 接口只有两个方法:

    1:   public   interface  ProtocolCodecFactory {
    2:   
    3:       public  ProtocolEncoder getEncoder(IoSession is)  throws  Exception;
    4:   
    5:       public  ProtocolDecoder getDecoder(IoSession is)  throws  Exception;
    6:  }
    7:   

没错,这个规约编解码工厂需要装配一个编码器(Encoder)和一个解码器(Decoder):

编码器:

    1:   public   class  ImageRequestEncoder  implements  ProtocolEncoder {
    2:   
    3:       public   void  encode(IoSession session, Object message, ProtocolEncoderOutput out)  throws  Exception {
    4:          ImageRequest request = (ImageRequest) message;
    5:          IoBuffer buffer = IoBuffer.allocate(12, false);
    6:          buffer.putInt(request.getWidth());
    7:          buffer.putInt(request.getHeight());
    8:          buffer.putInt(request.getNumberOfCharacters());
    9:          buffer.flip();
   10:          out.write(buffer);
   11:      }
   12:   
   13:       public   void  dispose(IoSession session)  throws  Exception {
   14:           // nothing to dispose 
   15:      }
   16:  }

解码器:

    1:   public   class  ImageRequestDecoder  extends  CumulativeProtocolDecoder {
    2:   
    3:       protected   boolean  doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)  throws  Exception {
    4:           if  (in.remaining() >= 12) {
    5:               int  width = in.getInt();
    6:               int  height = in.getInt();
    7:               int  numberOfCharachters = in.getInt();
    8:              ImageRequest request =  new  ImageRequest(width, height, numberOfCharachters);
    9:              out.write(request);
   10:               return  true;
   11:          }  else  {
   12:               return  false;
   13:          }
   14:      }
   15:  }

这里解码器不是直接从ProtocolDecoder继承的,为什么呢?因为实际中接受的一个数据包并不能保证包含完整的一帧报文,就是所谓的断帧的情况,如果用CumulativeProtocolDecoder,就不需要自己处理这种情况了,MINA框架会将未解码的数据保留,等下一包数据到来后继续尝试解码;

这里编码器的encode和解码器的doDecode方法就是实际用来进行应用层规约编解码的;其中ImageResuest是下行请求规约对应POJO.

整个类的协助关系如下图所示:

Filter过滤器处理完后,就交给Handler,做进一步业务处理;

Response部分的就不多罗嗦了,可以看 这里

至此对MINA框架用过的一些东西,从使用指南的角度做了一些总结,还有很多方面还没有用过,先留一个坑,等来日填补吧。MINA框架最吸引我的是这种设计思想,将通信、规约解析、业务处理分离得恰到好处,既不影响性能又方便扩展和替换。下一步希望从源代码的角度,学习一下其内部的实现思想。

 

分类:  Java

标签:  MINA

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Mina框架Filters的详细内容...

  阅读:52次