Apache MINA---[フィルタ]


IoFilterはMINAの核心構成部分であり、重要な規則を提供している.IoServiceとIoHandlerの間のI/Oイベントとリクエストをすべて取得します.Webアプリケーションの開発経験があれば、サーブレットフィルタの「兄弟」と簡単に想像できます.多くの開梱されたフィルタは、ネットワークアプリケーションの開発速度を促進するために提供され、これらのフィルタを使用することで、典型的な横方向の注目点を簡略化することができます.例えば、次のようにします.
    1.LoggingFilterはすべてのイベントとリクエストを記録します
    2.ProtocolCodecFilterは、入力されたバイトストリームを単純なメッセージオブジェクトに変換します.逆も同様です.
    3.CompressionFilter圧縮データ
    4.SSLFilter SSL-TLS-StartTLSサポートを追加
    5.もっと...
直接IoFilterインタフェースを実装する代わりにIoAdapterクラスを継承することができます.メソッドを上書きしない限り、受信イベントはすべて次のフィルタに直接転送される.
//              ,    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とmessageSetを同時に実現する必要があります.フィルタがこのような変換をしていない場合は、このような実現をお勧めします.以上のように、カスタムフィルタは、この2つの方法を直接実現する.(私はそう理解していますが…)
以下に原文を示す.
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.