![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e6f04cf)
現在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も見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
ブラウザの×ボタン(閉じるボタン)押下時のイベントをひろいたい
JavaScript
-
JavaScriptで ブラウザの閉じるを無効化に
JavaScript
-
ブラウザを閉じたときにログアウト処理を実行するには
その他(コンピューター・テクノロジー)
-
-
4
JSP+Servletで終了ボタン
Java
-
5
Javascript_submit()完了後に処理したい
JavaScript
-
6
閉じるボタンのクリックイベント!?
Microsoft ASP
-
7
ブラウザの右上にあるボタンを消すには?
HTML・CSS
-
8
Eclipseで、プロジェクト名のところに赤いバッテンのエラーマークが
Java
-
9
Webブラウザの閉じるボタン無効化についての質問
JavaScript
-
10
javascriptでセッションの削除をする例について プレゼント商品申し込み確認画面をjspで作成
JavaScript
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンピュータへの接続数が最大...
-
コネクション・セッション・ト...
-
ブラウザの×(閉じる)ボタンの...
-
DVD-Rの「セッションを閉じる」...
-
ASP.net MVC セッションハイジ...
-
SESSIDってなんですか?
-
ASP.NET 電卓計算
-
ブラウザを閉じてもセッション...
-
大量のTCPセッションについて
-
会社への勤怠届出にGoogleフォ...
-
CD-Rに追記したときに消え去っ...
-
DataGridViewのチェックボック...
-
getParameterで値が取得できず...
-
リンクでPOSTデータを送信する...
-
htmlでsubmit送信時、actionよ...
-
Webページ上のボタン等の位置を...
-
c# 文字列の最後から1文字削除...
-
Accessの画面更新を一時的に停...
-
VBAで早押しゲームを作りたい
-
HTMLボタンの文字色を変え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コネクション・セッション・ト...
-
コンピュータへの接続数が最大...
-
会社への勤怠届出にGoogleフォ...
-
DVD-Rの「セッションを閉じる」...
-
ブラウザの×(閉じる)ボタンの...
-
ブラウザを閉じずにセッション...
-
セッションIDを取得したい
-
DVDの中身が表示されません。
-
WCFのwsDualHttpBindingについて
-
ASP.NET 電卓計算
-
ルータのPPPのランプの色が変
-
CD-Rに追記したときに消え去っ...
-
自分のPCへアクセスしているコ...
-
JSPでポップアップウィンド...
-
遠隔操作されてる?
-
ショッピングカートのプログラ...
-
別ブラウザにセッションを渡す...
-
セッション変数の破棄と再設定
-
javaでのアクセスカウント
-
WebBrowserを初期化
おすすめ情報