JSP は新星として、サーバー プログラミング環境で一定の地位を占めることができます。これは、一連の業界標準を適切にサポートしていることと密接に関係しています。セッションは、それが提供するインフラストラクチャの 1 つです。プログラマは、クライアントでの実装方法を気にすることなく、シンプルなセッションベースのユーザー管理を簡単に実装できます。最近では、オンライン ユーザーに対処する方法がいくつかあります。
1 つは、ページの更新がユーザーによって制御され、サーバーが 30 分などのタイムアウトを制御し、時間が経過すると、アクションがなければユーザーが追い出されることです。この方法の利点は、ユーザーがログアウトを忘れた場合でも、他のユーザーによる悪意のある操作を防ぐことができることです。欠点は、時間がかかり、この制限時間を超える作業を行っている場合、送信時に再度ログインする必要がある場合があることです。元のリーフ表面が再び破損することを余儀なくされた場合、これまでの作業が失われる可能性があります。実装の観点から見ると、これが最も単純であり、サーバー側はデフォルトでこのモードを実装します。
もう 1 つの方法は、サイトがフレーム構造を採用しており、常に更新されるフレームまたは非表示の iframe があるため、追い出されることはありません。ただし、オンラインかどうかを判断するには、サーバーが を設定する必要があります。この放浪時間を超えると、この自動的に更新されるページ以外のページを更新しないと、オンラインではなくなったとみなされます。このアプローチの典型的な例は xici.net です。 その利点は、継続的な更新を使用して、ネチズン間でのメッセージの送信など、サーバー プッシュのような機能を実装できることです。
どのモードを使用する場合でも、現在オンラインのすべてのユーザーを参照するには、いくつかの追加作業を行う必要があります。サーブレット API にはセッション リストを取得する API はありません。
ここで使用できるのはリスナーです。サーブレット 2.2 と 2.3 の仕様は少し異なります。 2.2 の HttpSessionBindingListener は、HTTPSession の属性が変更されたときに通知するクラスを実装できます。 HttpSessionAttributeListener も 2.3 で導入されました。私が使用している環境は Visual 時代の Java 4 および JRun サーバー 3.1 であるため、これらは Servlet 2.3 プログラミングを直接サポートしていません。ここでは、
新しいクラスを作成する必要があります。 HttpSessionBindingListener インターフェイスを実装します。このインターフェイスには 2 つのメソッドがあります。
public void valueBound(HttpSessionBindingEventeventevent)
public voidvalueUnbound(HttpSessionBindingEventevent)
Session.addAttribute(String,Object) を実行するときに、HttpSessionBindingListener インターフェイスを Attribute として実装するクラスを追加している場合、Session は通知します。クラスを作成し、valueBound メソッドを呼び出します。逆に、Session.removeAttribute メソッドは valueUndound メソッドに対応します。
パブリック クラス HttpSessionBinding は javax.servlet.http.HttpSessionBindingListener を実装します
{
ServletContext アプリケーション = null;
public HttpSessionBinding(ServletContext アプリケーション)
{
素晴らしい();
if(アプリケーション==null)
throw new IllegalArgumentException("Null アプリケーションは受け入れられません。");
this.application = アプリケーション;
}
public void valueBound(javax.servlet.http.HttpSessionBindingEvent e)
{
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null)
{
activeSessions = 新しい Vector();
}
JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");
if (セッションユーザー != null)
{
activeSessions.add(e.getSession());
}
application.setAttribute("activeSessions",activeSessions);
}
public void valueUnbound(javax.servlet.http.HttpSessionBindingEvent e)
{
JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");
if (セッションユーザー == null)
{
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions != null)
{
activeSessions.remove(e.getSession().getId());
application.setAttribute("activeSessions",activeSessions);
}
}
}
} |
JDBCUser クラスが任意の User クラスであると仮定します。ユーザーログインを実行するときは、User クラスと HttpSessionBinding クラスの両方をセッションに追加します。
このようにして、ユーザーがログインするたびに、アプリケーションの属性「activeSessions」ベクトルにレコードが追加されます。セッションがタイムアウトになると、valueUnbound がトリガーされ、タイムアウトが近づいているセッションがこのベクトルから削除されます。
パブリックボイドログイン()
ACLException、SQLException、IOExceptionをスローします
{
/* JDBC ユーザークラスを取得 */
if (ユーザー != null)
{
ログアウト();
}
{
// セッションがタイムアウトした場合、またはユーザーがログインしなかった場合は、ターゲット URL を一時的に保存します。
JDBCUserFactory uf = new JDBCUserFactory();
if ( (this.request.getParameter("userID")==null) || (this.request.getParameter("password")==null) )
{
throw new ACLException("有効なユーザー名とパスワードを入力してください。");
}
JDBCUser ユーザー = (JDBCUser) uf.UserLogin(
this.request.getParameter("ユーザーID"),
this.request.getParameter("パスワード") );
user.touchLoginTime();
this.session.setAttribute("ユーザー",ユーザー);
this.session.setAttribute("BindingNotify",new HttpSessionBinding(アプリケーション));
}
} |
ログイン時に、User と BindingNotofy 目的クラスをセッションに追加します。ログアウトするときは、activeSessions ベクター内のセッションをアクティブに削除する必要があります。 |
|
これら 2 つの関数は HttpSessionManager クラスにあり、このクラスは jsp のアプリケーション グローバル オブジェクトを参照します。このクラスの他のコードはこの記事とは関係がなく、非常に長いので投稿しません。 JSPでの使い方を見てみましょう。 ログイン フォームが doLogin.jsp に送信され、そのフォームに UserName フィールドとパスワード フィールドが含まれているとします。抜粋抜粋: |
|
現在オンラインのユーザーのリストを取得する方法を見てみましょう。 |
|
上記のコードは、アプリケーションから activeSessions を取得し、特定の時間を表示します。 BeaconDate クラスは、フォーマットされた時刻クラスであると想定されます。 このようにして、オンライン ユーザーのリストを表示するためのフレームワークが得られます。オンライン ユーザー リストのページングやその他の機能については、この記事とは無関係なので説明しません。 これは、セッション タイムアウト メカニズムに依存する非リフレッシュ モデルの例です。私の同僚の sonymusic は、各メーカーの考え方が異なるため、これは信頼できない場合が多いと指摘しました。この要件を考慮すると、各リーフ表面がリフレッシュされるときに、現在のユーザーによる最後の使用からの時間が所定の時間値を超えているかどうかを判断する必要がある。これは基本的にセッション タイムアウトを自分で実装することになります。リフレッシュ モデルを実装する必要がある場合は、葉の表面ごとにリフレッシュを判断するこの方法を使用する必要があります。 |