[Servlet]listenerモニターを配置して詳しく説明します。


原文の住所:
http://blog.csdn.net/opnmzxcvb/archive/2009/09/15/4554329.aspx
1、どのようにHttpSession Listenerを使ってsessionの廃棄を監督しますか?
2、どのようにHttpSession BindingListenerを使ってsessionの廃棄を監督しますか?
一、HttpSession Listenerを使ってOnline UserListenerを作成します。

package anni;

import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionEvent;

public class OnlineUserListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent event) {
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        ServletContext application = session.getServletContext();

        //         
        String username = (String) session.getAttribute("username");

        //            
        List onlineUserList = (List) application.getAttribute("onlineUserList");
        onlineUserList.remove(username);

        System.out.println(username + "    。");
    }

}

ラインOnUserListenerはHttpSession Listener定義の二つの方法を実現しました。session Created()とsession Destroyed()。この2つの方法は,現在の応用におけるsessionの作成と破壊状況をモニターすることができる。私達のところはsession Destroyedまでsession廃棄時に操作すればいいです。
HttpSession Eventから廃棄されるセッションを取得し、sessionのユーザー名を得て、オンラインリストから削除します。最後の文はconsoneに情報を印刷して、操作が成功するようにヒントを与えます。これはデバッグ用のために、正常運行時に削除すればいいです。
モニターを作動させるために、web.xmlに追加します。

<listener>
  <listener-class>anni.OnlineUserListener</listener-class>
</listener>


以下の二つの場合にsession Destoryed(会話破壊)イベントが発生します。
1、session.invalidate()方法を実行する場合。
LogoutServlet.javaでsession.invalidate()を実行すると、session Destory()がオンラインユーザーリストから現在のユーザーを削除するようにトリガされますので、Logout Servlet.javaでオンラインリストを操作する必要はありません。

public void doGet(HttpServletRequest request,HttpServletResponse response)
    throws ServletException, IOException {
    //   session
    request.getSession().invalidate();
    //   
    response.sendRedirect("index.jsp");
}
2、ユーザーが長い間サーバにアクセスしていないと、セッションの最大タイムアウト時間を超えて、サーバはタイムアウトのセッションを自動的に廃棄します。
セッションタイムアウト時間はweb.xmlで設定できます。タイムアウト効果が見やすいようにタイムアウト時間を最小値に設定します。

<session-config>
    <session-timeout>1</session-timeout>
</session-config>
時間単位は一分で、整数しかないです。ゼロか負の数なら、セッションは永遠にタイムアウトしません。
対応例は08-01で、Online UserListenerが正常に実行できるかどうかを検証するために、私達は2人のユーザーを登録して、その中の1つはログアウトをクリックして、もう1つは1分待って、そしてOnlineの中で出力の情報を見ることができます。
  ダウンロード(13.11 KB)
2009-7-1 14:37
二、HttpSession BindingListenerを使用する
HttpSession BindingListenerはモニターと呼ばれていますが、使い方はHttpSession Listenerとは全く違います。私たちは実際にそれがどうやって使うかを見てみます。
私達のOnline UserBindingListenerはHttpSession BindingListenerインターフェースを実現しました。インタフェースでは2つの方法を定義しています。
sessionに対してデータバインディングとは、session.set Attributeを呼び出してHttpSession BindingListenerをsessionに保存することです。私たちはこのステップをLoginnServlet.javaで行います。

public void valueBound(HttpSessionBindingEvent event) {
    HttpSession session = event.getSession();
    ServletContext application = session.getServletContext();

    //           
    List onlineUserList = (List) application.getAttribute("onlineUserList");
    //       ,     
    if (onlineUserList == null) {
        onlineUserList = new ArrayList();
        application.setAttribute("onlineUserList", onlineUserList);
    }
    onlineUserList.add(this.username);
}
これはHttpSession BindingListenerとHttpSession Listenerの最大の違いです。HttpSession Listenerはweb.xmlにセットするだけで、アプリケーション全体のsessionを傍受できます。HttpSession BindingListenerは、実用化された後、あるセッションに入れてこそ、傍受が可能です。
モニターの範囲から比較すると、HttpSession Listenerは一回設置すれば全てのセッションをモニターできます。HttpSession BindingListenerは通常は一対一です。
このような違いはHttpSession BindingListenerの優勢を達成しました。私達は各listenerを一つのusernameに対応させることができます。このようにして毎回sessionでusernameを読み込む必要がなく、更にすべての操作オンラインリストのコードをlistenerに移して、メンテナンスしやすいです。
valueBound()方法のコードは以下の通りです。

public void valueUnbound(HttpSessionBindingEvent event) {
    HttpSession session = event.getSession();
    ServletContext application = session.getServletContext();

    //            
    List onlineUserList = (List) application.getAttribute("onlineUserList");
    onlineUserList.remove(this.username);

    System.out.println(this.username + "  。");
}
ここで直接にlistenerのusernameを使ってオンラインリストを操作してもいいです。sessionにusernameがあるかどうか心配しなくてもいいです。
valueUnboundのトリガ条件は以下の3つの場合です。
session.invalidate()を実行する場合。
sessionがタイムアウトし、自動廃棄された場合。
session.set Attributeを実行します。或いはsession.removeAttribute;listenerをsessionから削除する場合。
したがって、listenerをsessionから削除しない限り、sessionの破壊を傍受することができます。