IoFilter是MINA的核心组成部分,它提供了重要的规则.它过来所有在IoService和IoHandler之间的I/O事件和请求.如果你有过相关的Web应用开发经验,你可以把它简单的想象成Servlet过滤器的"兄弟".许多开箱即用的过滤器被提供用来促进网络应用开发速度,通过使用这些过滤器,可以简化典型的横向关注点,例如:
1.LoggingFilter 记录所有的事件和请求
2.ProtocolCodecFilter 将输入的字节流转化成简单的消息对象,反之亦然
3.CompressionFilter 压缩数据
4.SSLFilter 添加SSL-TLS-StartTLS支持
5.更多...
你可以继承IoAdapter类来替代直接实现IoFilter接口.除非覆盖方法,不然所有收到的事件将被转直接转发到下一个过滤器.
//除非你想自己实现所有相关方法,不然继承IoFilterAdapter是更简单的做法public class MyFilter extends IoFilterAdapter { // 需要注意的是,sessionCreated事件必须在I/O Processor线程中执行,不能转发给其他线程 @Override public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { nextFilter.sessionCreated(session); } @Override public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { nextFilter.sessionOpened(session); } // ProtocolCodecFilter使用空缓冲区来作为一个内部信号,所以,当自定义Filter被放置在ProtocolCodecFilter之前时,需要进行如下判断 @Override public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest request) { Object message = request.getMessage(); if (message instanceof ByteBuffer && !((ByteBuffer) message).hasRemaining()) { nextFilter.filterWrite(session, request); return; } } @Override public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest request) throws Exception { Object message = request.getMessage(); if (message instanceof ByteBuffer && !((ByteBuffer) message).hasRemaining()) { nextFilter.messageSent(session, request); return; } }}
备注:
官方文档说明中描述,如果你的过滤器对输入输出对象做了类型转换,那么你必须要同时实现filterWrite和messageSent,如果你的过滤器没有做这样的转换,也建议这样实现....综上所述,自定义过滤器直接实现这两个方法.(我是这么理解的...)
下面给出原文:
If you are going to transform an incoming write request via IoSession.write(), things can get pretty tricky. For example, let's assume your filter transforms HighLevelMessage to LowLevelMessage when IoSession.write() is invoked with a HighLevelMessage object. You could insert appropriate transformation code to your filter's filterWrite() method and think that's all. However, you have to note that you also need to take care of messageSent event because an IoHandler or any filters next to yours will expect messageSent() method is called with HighLevelMessage as a parameter, because it's irrational for the caller to get notified that LowLevelMessage is sent when the caller actually wrote HighLevelMessage. Consequently, you have to implement both filterWrite() and messageSent() if your filter performs transformation.
Please also note that you still need to implement similar mechanism even if the types of the input object and the output object are identical (e.g. CompressionFilter) because the caller of IoSession.write() will expect exactly what he wrote in his or her messageSent() handler method.