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 メソッドに対応します。
public class HttpSessionBindingimplements javax.servlet.http.HttpSessionBindingListener
{
ServletContext application = null;
public HttpSessionBinding(ServletContext application)
{
super()
if (application ==null)
throw new IllegalArgumentException("Null application is not accept.")
; .application = application;
}
public void valueBound(javax.servlet.http.HttpSessionBindingEvent e)
{
Vector activeSessions = (Vector) application.getAttribute("activeSessions")
if (activeSessions == null)
{
activeSessions = new Vector();
JDBCUser
sessionUser = (JDBCUser)e.getSession().getAttribute("user");
if (sessionUser != 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 (sessionUser == null)
{
Vector activeSessions = (Vector) アプリケーション.getAttribute("activeSessions");
if
(activeSessions != null)
{
activeSessions.remove(e.getSession().getId());
application.setAttribute
(
"
activeSessions"
,activeSessions);
Class は任意の User クラスです。ユーザーログインを実行するときは、User クラスと HttpSessionBinding クラスの両方をセッションに追加します。
このようにして、ユーザーがログインするたびに、アプリケーションの属性「activeSessions」ベクトルにレコードが追加されます。セッションがタイムアウトになると、valueUnbound がトリガーされ、タイムアウトになるセッションがこのベクトルから削除されます。
public void login()
throws ACLException,SQLException,IOException
{
/* get JDBC User Class */
if (user != null) )
{
logout ();
}
{
// セッションがタイムアウトした場合、またはユーザーがログインしなかった場合、ターゲット URL を一時的に保存し
ます
。
=null) || (this.request.getParameter("password")==null) )
{
throw new ACLException("有効なユーザー名とパスワードを入力してください。")
}
JDBCUser user = (JDBCUser) uf.UserLogin(
this .request.getParameter("userID"),
this.request.getParameter("password") );
user.touchLoginTime()
;
this.session.setAttribute("BindingNotify") ,new HttpSessionBinding (application));
}
}
ログイン時に、User および BindingNotofy 目的クラスをセッションに追加します。ログアウトするときは、activeSessions ベクター内のセッションをアクティブに削除する必要があります。
public void logout()
throws SQLException,ACLException
{
if (this.user == null && this.session.getAttribute("user")==null)
{
return ;
}
ベクトル
activeSessions = (Vector) this.application.getAttribute("activeSessions");
if
(activeSessions
!= null)
{
application.setAttribute("activeSessions",activeSessions);
util.Enumeration e = this.session.getAttributeNames();
while (e.hasMoreElements())
{
String
s = (String)e.nextElement(
s);
this.user.
これら2
つ
の関数は、JSP のアプリケーション グローバル オブジェクトを参照します
。
このクラスの他のコードはこの記事とは関係がなく、非常に長いので投稿しません。
JSPでの使い方を見てみましょう。
ログイン フォームが doLogin.jsp に送信され、そのフォームに UserName フィールドとパスワード フィールドが含まれているとします。抜粋:
<%
HttpSessionManager hsm = new HttpSessionManager(application,request,response);
try
{
hsm.login();
}
catch (UserNotFoundException e)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=User%20does%20not %20exist .");
return;
}
catch (InvalidPasswordException e2)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
return;
}
catch (Exception e3)
{
%> エラー:<%=e3.toString( ) %><br>
再ログインするには、<a href="login.jsp">ここ</a> を押してください。
<% return;
}
response.sendRedirect("index.jsp");
見てみましょう
。
have now 現在オンラインのユーザーのリストを取得する方法。
<body bgcolor="#FFFFFF">
<テーブル cellpacing="0" cellpadding="0" width="100%">
<tr>
<td style="width:24px">セッションId
</td>
<td style= "width:80px" >ユーザー
</td>
<td style="width:80px" >ログイン時刻
</td>
<td style="width:80px" >最終アクセス時刻
</td>
</tr>
<%
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions==
null)
{
activeSessions = new Vector()
;
イテレータ it = activeSessions.iterator(); ;
while (it.hasNext())
{
HttpSession sess = (HttpSession)it.next();
JDBCUser
sessionUser = (JDBCUser)sess.getAttribute("user");
():"なし";
%>
<tr>
<td nowrap=''><%= sess.getId() %></td>
<td nowrap=''><%= userId %></td>
<td nowrap=''>
<%= BeaconDate.getInstance( new Java.util.Date(sess.getCreationTime())).getDateTimeString()%></td>
<td class="<%= stl %>3 " nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getLastAccessedTime())).getDateTimeString()%></td>
</tr>
<%
}
%>
</table>
</body>
上記のコードはアプリケーションからactiveSessionsを取得し、特定の時刻を表示します。 BeaconDate クラスは、フォーマットされた時刻クラスであると想定されます。
このようにして、オンライン ユーザーのリストを表示するためのフレームワークが得られます。オンライン ユーザー リストのページングやその他の機能については、この記事とは無関係なので説明しません。
これは、セッション タイムアウト メカニズムに依存する非リフレッシュ モデルの例です。私の同僚の sonymusic は、各メーカーの考え方が異なるため、これは信頼できない場合が多いと指摘しました。この要件を考慮すると、各リーフ表面がリフレッシュされるときに、現在のユーザーによる最後の使用からの時間が所定の時間値を超えているかどうかを判断する必要がある。これは基本的にセッション タイムアウトを自分で実装することになります。リフレッシュ モデルを実装する必要がある場合は、葉の表面ごとにリフレッシュを判断するこの方法を使用する必要があります。