
現在servlet,JSPでwebサイトを作っていて(webserver:Apache2.x - Tomcat4.x)、
ユーザーの2重ログイン防止の為に
(1)ユーザーが×(閉じる)ボタンを押した時
(2)セッションタイムアウトになった時
のイベントを拾ってDBへの書き込み処理をしたいのですが、
どのようにやればよいのかわかりません。
((2)の場合SessionListenerというのがあると聞いたのですが、使い方がいまいち分からず・・・)
servletプログラミングで上の2つのイベントの拾い方をご存知の方がいたら教えていただきたいです。
よろしくお願いします。
No.6ベストアンサー
- 回答日時:
すみません。
見落としていました。
No.3 の補足で、
> HttpSessionBindingListenerを実装したクラスでgetAttribute()できました
と記述されていますが、これ自体が問題です。
No.4 で記述したように
> 2.アプリケーションでinvalidate()が呼ばれてセッション自体が消えた
> 3.セッションタイムアウトでセッション自体が消えた
という場合にも、valueUnBound()が呼ばれます。
そして、これらの場合、セッションが無効化されてから valueUnBound()
が呼ばれてしまうので、今問題になっているような状況になります。
これについては、ログオフ処理で利用するHttpSessionの情報を
1つのクラスにまとめ、そのクラスに HttpSessionBindingListener
を実装します。そして、valueUnBound() で自分自身のフィールドに
アクセスして処理を行うようにします。
こうすることで、invalidate() でセッションが無効化されて valueUnBound()
が呼ばれても、valueUnBound() を持つクラスのインスタンス自体は
破壊されていないので、情報が取得できます。
すなわち、
> valueUnBound()の中では
> 1)セッション情報を取り出す
> 2)取り出した値を使ってDBに書き込みする
> 3)セッション情報を破棄する
2) で本来取り出されるクラスにvalueUnBound() を実装して、
そこでDBへの書き込みを行うようにします。
この場合、1) は特に不要(自分自身に情報が存在するから)ですし、
3) はログオフの処理を行っている場所で呼び出すようになります。
「ログオフ処理で利用するHttpSessionの情報を
1つのクラスにまとめ、そのクラスに HttpSessionBindingListener
を実装し」たら、うまく処理できるようになりました。
丁寧な回答でとても分かりやすかったです。
本当に助かりました。ありがとうございました。
No.5
- 回答日時:
> ただ、現在「removeAttribute() メソッドを呼び出している場所(ログオフ処理)で、
> invalidate() メソッドを呼ぶようする」と、
> 1.removeAttribute()でvalueUnBound()が呼ばれ、
> 2.invalidate()でまたvalueUnBound()が呼ばれてしまうらしく、invalidate()で呼ばれた時の
> valueUnBound()はgetAttribute()出来ずにExceptionで落ちてしまいます。
どうも、私の書き方に問題があったような、、、
> removeAttribute() でセッションオブジェクトから特定のオブジェクトを削除してから
> セッションを無効化するのであれば、removeAttribute() メソッドを呼び出している場所で、
> invalidate() メソッドを呼ぶようするだけで構わないのでは?
これは、現在ログオフ処理で行っている、removeAttribute()を
invalidate()に置き換えては?という意味です。
invalidate()を実行すると既存のセッションオブジェクト自体が
削除されるわけですから、わざわざ直前でremoveAttribute()を呼び出す
意味がないように思えますが、どうでしょうか?
この回答への補足
invalidate()に置き換えた場合なのですが、
invalidate()でvalueUnBound()が呼ばれた場合、セッション情報が破棄されているらしく、
getAttribute("xx")で自分で詰めたセッションの情報が取り出せません。
(質問が堂堂巡りのようになってしまいすみません。)
上記valueUnBound()の中では
1)セッション情報を取り出す
2)取り出した値を使ってDBに書き込みする
3)セッション情報を破棄する
という処理をしたいのですが、invalidate()の場合、
3)の要件を先に満たしてしまうために1)の処理ができないようです。
No.4
- 回答日時:
> ちなみにremoveAttribute()でvalueUnBound()を呼び出した時に、
> セッション情報の破棄をしたいのですが、valueUnBound()メソッドの中
> でsession.invalidate()をすると「無効化されたセッションです」と
> いうエラーで落ちてしまいます。
これは、例えば、セッションが削除(HttpSession#invalidate()や
タイムアウト)されたときにvalueUnBound() が呼ばれたせいだと思います。
removeAttribute() でセッションオブジェクトから特定のオブジェクトを削除してから
セッションを無効化するのであれば、removeAttribute() メソッドを呼び出している場所で、
invalidate() メソッドを呼ぶようするだけで構わないのでは?
valueUnBound() メソッドは、
1.アプリケーションでremoveAttribute()が呼ばれてセッションから消された
2.アプリケーションでinvalidate()が呼ばれてセッション自体が消えた
3.セッションタイムアウトでセッション自体が消えた
という全てのパターンで呼ばれてしまいます。
> removeAttribute()したらsession.invalidate()は必要ないのでしょうか?
removeAttribute() はセッションオブジェクトから特定のオブジェクトを削除
するためのメソッドで、HttpSession#invalidate() はセッションオブジェクトを
破棄するメソッドですから、必要です。
ただし、明示的に破棄しなくても、一定時間後タイムアウトでなくなりますが。。。
この回答への補足
的確でわかりやすい回答をありがとうございます。
ただ、現在「removeAttribute() メソッドを呼び出している場所(ログオフ処理)で、
invalidate() メソッドを呼ぶようする」と、
1.removeAttribute()でvalueUnBound()が呼ばれ、
2.invalidate()でまたvalueUnBound()が呼ばれてしまうらしく、invalidate()で呼ばれた時の
valueUnBound()はgetAttribute()出来ずにExceptionで落ちてしまいます。
そして、2.のinvalidate()で呼ばれた時のvalueUnBound()では、セッションオブジェクト自体は残っているらしく(getId()でセッションIDなどは取得できる)、
if(session==null)などでは判定できず、removeAttribute()のvalueUnBound()メソッドが呼ばれたのか、invalidate()のvalueUnBound()が呼ばれたのか判断できずにいます。
このような場合はremoveAttribute()で設定したセッション情報を1つ1つすべて削除していくしかないのでしょうか。
(ちなみにremoveAttribute()のvalueUnBound()の中でもinvalidate()してみましたが、やっぱりダメでした。これは当然ですかね(^_^;))
分かりにくい説明ですみませんが、重ねて教えていただけたらありがたいです。よろしくお願いします。
No.3
- 回答日時:
> String str = (String)se.getSession().getAttribute("xx");
> ができませんでした。(se.getId()とかはできるのに・・・)
> setAttribute()で詰め込んだ値を取り出す方法はないものでしょうか・・・。
これは、HttpSessionBindingListenerインタフェースを使います。
というのは、HttpSessionListener#sessionDestroyed() は、
「セッションが削除された」ときに呼ばれるため、セッションの情報には
アクセスできません。
この代わりに、
public MyBindingClass implements HttpSessionBindingListener {
private String foo;
public void valueBound(HttpSessionEvent se) {
}
public void valueUnBound(HttpSessionEvent se) {
// セッションからこのクラスが削除されるときに
// 実行される。foo に合わせて処理したり、、、
}
}
というクラスを作成して、これをSessionにsetAttribute()してやります。
この回答への補足
HttpSessionBindingListenerを実装したクラスでgetAttribute()できました!!ありがとうございます。
ちなみにremoveAttribute()でvalueUnBound()を呼び出した時に、セッション情報の破棄をしたいのですが、valueUnBound()メソッドの中でsession.invalidate()をすると「無効化されたセッションです」というエラーで落ちてしまいます。
removeAttribute()したらsession.invalidate()は必要ないのでしょうか?
稚拙な質問で申し訳ないのですが、教えていただけるとありがたいです。よろしくお願いします。
No.2
- 回答日時:
こんにちは
>ユーザーの2重ログイン防止の為に
これはよくやることなので大手のソフト開発の
現場では定石となっている場合が多いです。
>(1)ユーザーが×(閉じる)ボタンを押した時
これは残念ながら拾うことができません。
>(2)セッションタイムアウトになった時
1.HttpSessionBindingListenerという
リスナーを設定することによって
たとえば30分通信が無かったら接続をきるなどの
処理ができます。
(使い方はHttpSessionの中で通常の
リスナーのようにaddListenerすればよかったと思います)
たしか原田洋子さんの本に載っていたと思うのですが・・・
2.web-xmlの中でも指定できるみたいです。
これはやってみたこと無いのでちょっとわからないですが・・・
参考URL:http://java-house.jp/ml/archive/j-h-b/030594.html
この回答への補足
HttpSessionBindingListenerの方はまだよくわからなくて試していません・・・。
ただ、HttpSessionListenerはgetAttribute()で値がとれなかったので、こちらの方法を頑張って試してみます。
ちなみに
HttpSessionBindingListener
と
HttpSessionListener
はどう違うのでしょうか?
No.1
- 回答日時:
(1) についてはServlet、JSPでは不可能です。
これはクライアント側の話なので、VBScriptとかであれば
実現可能です。
その場合は、IE限定になりますが。。。
(2) については、Servlet2.3以上をサポートするコンテナ上で
HttpSessionListenerインタフェースを実装したクラスを用意して
web.xml に設定を記述すれば実現できます。
public MyListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
// ここにセッションが作られたときの処理
}
public void sessionDestroyed(HttpSessionEvent se) {
// ここにセッションが削除されるときの処理
}
}
-- web.xml --
<listener>
<listener-class>MyListener</listener-class>
</listener>
-------------
この回答への補足
HttpSessionListenerを実装したクラスを作って、やってみました。
(1)の×ボタンのイベントを拾うのやっぱり無理みたいですね。
(2)についてはこの方法だと、
String str = (String)se.getSession().getAttribute("xx");
ができませんでした。(se.getId()とかはできるのに・・・)
setAttribute()で詰め込んだ値を取り出す方法はないものでしょうか・・・。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンピュータへの接続数が最大...
-
コネクション・セッション・ト...
-
CDの編集について
-
JSPでポップアップウィンド...
-
セッションIDを取得したい
-
サーバー上の全セッション変数...
-
DVD-Rの「セッションを閉じる」...
-
フォームデータをlocation.repl...
-
会社への勤怠届出にGoogleフォ...
-
ASP.NET 電卓計算
-
DVDの中身が表示されません。
-
助けて下さい!!セッション変...
-
大量のTCPセッションについて
-
ブラウザの×(閉じる)ボタンの...
-
Webページ上のボタン等の位置を...
-
getParameterで値が取得できず...
-
ASP.NetのGridViewで任意の行ク...
-
GridViewの項目編集(初歩)
-
VBAで一時中断したプログラムの...
-
aspxをhtmlに変換する方法について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コネクション・セッション・ト...
-
DVD-Rの「セッションを閉じる」...
-
コンピュータへの接続数が最大...
-
JSPでポップアップウィンド...
-
ASP.net MVC セッションハイジ...
-
画像のようにユーザーが登録し...
-
CDRのデータ復旧
-
会社への勤怠届出にGoogleフォ...
-
セッションIDを取得したい
-
SSLを使用したページのセッショ...
-
ブラウザの×(閉じる)ボタンの...
-
セッション管理
-
ルータのPPPのランプの色が変
-
ブラウザを閉じずにセッション...
-
セッションハイジャックの対策...
-
思うように セッションの破棄...
-
Dreamweaver+PHP+MySQL・オスス...
-
PHPのセッションについて
-
セッション変数の破棄と再設定
-
接続可能セッションについて
おすすめ情報