現在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で質問しましょう!
似たような質問が見つかりました
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- その他(コンピューター・テクノロジー) PC利用中に勝手に起動する窓を消し去る方法を教えて下さい。 1 2023/05/08 16:48
- Excel(エクセル) Excelのマクロについてご教授ください 2 2023/02/25 09:43
- Excel(エクセル) excelvbaのenableeventsについて 3 2022/08/30 11:20
- Windows 10 ファイルエクスプローラーでフォルダを閉じる操作について 2 2022/10/15 11:06
- その他(アニメ・マンガ・特撮) イベントの参加について 1 2022/07/14 08:23
- Windows 10 ソフトの実行を自動化したいです。 1 2022/10/15 16:09
- Access(アクセス) Access 登録ボタンからサブフォームの更新 1 2022/07/22 10:23
- Facebook Facebookのメッセンジャーのサインインの方法について 1 2022/06/08 22:12
- イヤホン・ヘッドホン・補聴器 マイク付き有線イヤホン(WEB会議に使用)のおすすめありますか? 4 2022/04/07 13:33
このQ&Aを見た人はこんなQ&Aも見ています
-
新NISA制度は今までと何が変わる?非課税枠の拡大や投資対象の変更などを解説!
少額から投資を行う人のための非課税制度であるNISAが、2024年に改正される。おすすめの銘柄や投資額の目安について教えてもらった。
-
ブラウザの×ボタン(閉じるボタン)押下時のイベントをひろいたい
JavaScript
-
JavaScriptで ブラウザの閉じるを無効化に
JavaScript
-
ブラウザを閉じたときにログアウト処理を実行するには
その他(コンピューター・テクノロジー)
-
-
4
Javascript_submit()完了後に処理したい
JavaScript
-
5
JSP+Servletで終了ボタン
Java
-
6
【C#/Java?】try-catchでcatchせずにfinallyは一般的?
その他(プログラミング・Web制作)
-
7
onbeforeunload時のwindow.openが効かないのです
JavaScript
-
8
子ウィンドウの存在確認
JavaScript
-
9
ブラウザの右上にあるボタンを消すには?
HTML・CSS
-
10
Webブラウザの閉じるボタン無効化についての質問
JavaScript
-
11
ブラウザを閉じた後もセッションが消えない
PHP
-
12
javascriptでセッションの削除をする例について プレゼント商品申し込み確認画面をjspで作成
JavaScript
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コネクション・セッション・ト...
-
コンピュータへの接続数が最大...
-
フォームデータをlocation.repl...
-
SESSIDってなんですか?
-
DVD-Rの「セッションを閉じる」...
-
WCFのwsDualHttpBindingについて
-
セッションIDを取得したい
-
Eclipseでクリーンが出来ない
-
c# 文字列の最後から1文字削除...
-
Accessの画面更新を一時的に停...
-
DataGridViewのチェックボック...
-
HTMLボタンの文字色を変え...
-
Webページ上のボタン等の位置を...
-
VBAで一時中断したプログラムの...
-
asp.net メッセージボックス表...
-
別画面で起動するとログインセ...
-
複数選択のListBoxでClickイベ...
-
VBAでこれってどういう意味でし...
-
同じソリューション内の別のプ...
-
ACCESS2010 WEBブラウザーコン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コネクション・セッション・ト...
-
DVD-Rの「セッションを閉じる」...
-
ブラウザの×(閉じる)ボタンの...
-
コンピュータへの接続数が最大...
-
ブラウザを閉じずにセッション...
-
セッションIDについて
-
Apacheでセッション管理
-
DVDの中身が表示されません。
-
WCFのwsDualHttpBindingについて
-
会社への勤怠届出にGoogleフォ...
-
フォームデータをlocation.repl...
-
自分のPCへアクセスしているコ...
-
ディスクのセッションを閉じる...
-
遠隔操作されてる?
-
SESSIDってなんですか?
-
CD-Rに追記したときに消え去っ...
-
Win8のIE8にて必ず新規セッショ...
-
ルータのPPPのランプの色が変
-
セッションIDを取得したい
-
ショッピングカートのプログラ...
おすすめ情報