- - PR -
jsp の におけるscopeについて
1
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2002-09-27 14:44
こんにちわ。
お知恵をお借りしたく投稿します。 現在以下のようなフローのシステムを作成しています。 1:ログイン画面(HTML) ↓ ↓postで送信 ↓ 2:ログイン機能部(Servlet) ここでgetSession(true)により新規session生成 ↓ ↓Dispatch ↓ 3:各種画面(JSP) ここで<jsp:useBean id="id" class="class" scope="session">と宣言 ↓ ↓postで送信 ↓ 4:各種機能部(Servlet) ここでgetSession(false)により既存session取得、nullであればエラー ↓ ↓Dispatch ↓ 5:各種結果画面(JSP) ここで<jsp:useBean id="id" class="class" scope="session">と宣言 上記のような作りの場合、期待する動きとして、 ・セッションがタイムアウトしない限りは正常に機能する。 ・セッションがタイムアウトすれば、あとの処理はすべて セッション切れのエラー画面表示 しかし下記のようにした場合、困った事象が発生します。 ・A機能使用画面(JSP)に遷移 ・A機能を使用し、セッションタイムアウトまで待つ。 ・再度A機能を使う。 ・セッションエラー発生 ・エラー発生後、再度A機能使用画面に遷移 ・再度A機能を使用 ・セッションエラーではなく、NullPointerException発生 調査したところ <jsp:useBean>が原因ではないかと思えてきました。 どうやら「・エラー発生後、再度A機能使用画面に遷移」の箇所で sessionを新たに作ってしまっているみたいです。 NullPointerExceptionはServletの中でbeanのメソッドを叩く時に 発生していることがわかりました。 jspがコンパイルされたjavaファイルからソースを見てみたのですが session = pageContext.getSession(); というな感じでsessionを取得しているみたいなんですが これはsessionがなければ作ってしまうのでしょうか? APIドキュメントにはそのへんのことは一切書いてありませんでした。 request#getSession(boolean)みたいな引数もないので 困っています。 それとも<jsp:useBean>の中に何か指定すれば良いのでしょうか? よろしくお願いします。 | ||||||||
|
投稿日時: 2002-09-27 15:22
<%@ page session="false"%>
になってますか。 >session = pageContext.getSession(); もう一歩踏み込むとJspFactoryクラスのgetPageContext()メソッドによってpageContextが生成されています。 このメソッドにpageディレクティブのセッション属性の値が渡されているようです。 | ||||||||
|
投稿日時: 2002-09-27 16:11
>ひろ様
回答ありがとうございます。 なるほど、僕の知識が薄かったようです。 そこで<%@ page session="false" %>について調べてみました。下記参考 http://www.atmarkit.co.jp/fjava/javafaq/jsp/jsp06.html それでは機能を使用するJSP内でログイン時に生成したセッションの中身を 見てしまっている場合はどうすればいいのでしょうか? 例えば下記のような場合 1:ログイン session生成 2:登録画面(JSP) ここでログイン時に得たユーザ名を表示したい。 3:登録処理(Servlet) session存在チェック 4:登録結果画面(JSP) 登録結果を表示 上記のような場合、1でsessionが新規で作られ、その後2,4 のいずれでもsessionを触っています。 <%@ page session="false"%> を指定した場合、jsp内でsessionを触る処理があった場合に コンパイルエラーになります。 よって2,4のjsp内では <%@ page session="true"%> という記述、もしくは省略する形が適当だと思ってるんですが 認識は合っているでしょうか? そしてこの場合も、セッションタイムアウトでエラーになった後に 再度2から処理しようとするとsessionが新たに作られるため、 投稿した内容と同じ事象が発生すると思います。 僕の希望としてはServlet内における request#getSession(boolean)みたいに sessionがあればそれを使い、なければnull返す。ってのを jspの中でもやってくれないのかなと・・。 | ||||||||
|
投稿日時: 2002-09-27 16:30
すみません、この部分にのみ反応して書いてしまいました。問題の解決になっていませんでしたね。 正常にログインして作られたセッションにはユーザID等の認証済みの情報を 持っているのですよね。 それでしたら、セッションからその値を取得してみてそれがNullであれば エラーとする。もしくはログインページにforwardするのはどうでしょうか。 | ||||||||
|
投稿日時: 2002-09-27 16:54
>ひろ様
>正常にログインして作られたセッションにはユーザID等の認証済みの情報を >持っているのですよね。 >それでしたら、セッションからその値を取得してみてそれがNullであれば >エラーとする。もしくはログインページにforwardするのはどうでしょうか。 確かにそうですね。 そのユーザIDはBeanの内部パラメータであり、Beanはsessionに格納されている。 ルートによってはsessionが切れた後、sessionが切れたまま、新しく生成されている 、また内部のbeanまでもが生成されちゃってる時があるってのがServlet側で意識する ことができないので、チェックとしては if( session == null ) { 第一のセッショエラーチェック } bean = (bean)session.getAttribute("bean); if( bean == null ) { 第二のセッションエラーチェック } if( bean.getPara() == null ) { 第三のセッションエラーチェック } 3重にしなきゃいけないのかな・・。つら・・。 ちなみにjspの中で <jssp:useBean id="id" class="class" scope="session"/> と記述しているのですが こうすると、session内のbeanまでが新規作成されるんですが この記述をしないで jsp内で <% Bean bean = (Bean)session.getAttribute("bean"); %> という風にすればbeanの新規作成は僕にゆだねらるのでしょうかね? そうすればsessionがタイムアウト後新規作成された場合、beanは 勝手に新規作成されないでnullが返ってくるのでbeanがnullかそうでないか によってチェックできる気がするんですが。 | ||||||||
|
投稿日時: 2002-09-27 19:01
まず、セッションタイムアウト後にサーブレットを実行してエラーになった場合は、セッションを使用しているJSPページではなくてセッションを使用しないページに送ってあげてはどうでしょうか。
ブラウザのキャッシュを利用されたくないページには下記のタグも多少役に立つと思います。 <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta http-equiv="Expires" content="0"> それでもキャッシュコントロールは完璧ではないので、JSP直接起動などのためにもロジック必要ですね。
そうですが、<jsp:useBean>の記述より前ではまだ生成されていないはずです。
ページの最初でこういったコードで判定してやってはどうでしょうか。 できれば別ファイルにしておいて、 <%@ include file="XXXXXXXXXX" %> としてやるとすっきりすると思います。 | ||||||||
|
投稿日時: 2002-09-30 09:53
>ひろ様
何度も回答ありがとうございます。 結局うまく行けるようになった感じがします。 あまりコードを変更するのもイヤだったので 僕が取った手段は以下のような感じです。 ・sessionを使用しないJSPファイル内では すべて<%@ page session="false" %>を記述 ・ログイン後sessionを生成するServlet内で session、およびBeanを生成する処理に加えて session.setAttribute("hoge", hoge)という 感じで判定用のチェックオブジェクトを格納。 (チェックオブジェクトは適当なStringです) ・sessionを使用するJSPおよびServlet内の頭で 以下のチェックロジックを記述 //セッションエラーチェック if( session == null ) { //エラー処理 return; } else if( session.getAttribute( "hoge" ) == null ) { //エラー処理 session.invalidate(); return; } こんな感じで、sessionがなければエラーとし、また不本意に作られて いたとしても(Beanまでもが作られていても)チェックフラグ用のオブジェクト がなければエラーとしました。 今のところ特に問題は出ていないのですが・・。 色々な助言ありがとうございました。 | ||||||||
1
