JSPではuseBeanというアクションを使ってセッションを通じてアクセス可能なオブジェクトを作成することができます。たとえば、
しかし、このuser変数に別のオブジェクトの参照を代入しても、別のページでそのオブジェクトを参照することはできません。たとえば、次のようなコードを考えてみましょう。
scope="session"の指定からは、userという変数が各ページより上の階層に作られるような構造をイメージしてしまいそうですが、実際にはそうではありません。useBeanで作られたuserは、あくまで「そのページだけ」で有効な変数で、セッション上のオブジェクトへの参照がその都度コピーされるのです。つまり、隣のページのuserとは、名前が同じ別の変数なのです。これは、JSPからJavaに変換されたソース(Tomcatのworkフォルダの中にあります)を見ると分かります。上の例のuseBeanアクションは次のようなコードに展開されています。
しかし、セッション上のオブジェクトを入れ替えることができないわけではありません。これにはsessionオブジェクトのsetAttributeメソッドを使います。次に例を示します。
※実は、私自身が何度もうっかりハマっているので忘れないように書きました。
<jsp:useBean class="jp.veltec.User" id="user" scope="session"/>
とすれば、Userクラスからuserという名前のオブジェクトが作成され、このオブジェクトをJSPコードの中で使用できます。セッションを通じて有効なオブジェクトを作るには、上記のようにscope="session"を指定します。これにより、あるページのuserと別のページのuserが同じオブジェクトを参照するようになります。たとえば、あるページでuser.setName("xxx")のようなメソッドでオブジェクトにユーザ名をセットし、別のページでuser.getName()のなどのメソッドでユーザ名を表示することができます。しかし、このuser変数に別のオブジェクトの参照を代入しても、別のページでそのオブジェクトを参照することはできません。たとえば、次のようなコードを考えてみましょう。
<jsp:useBean class="jp.veltec.User" id="user" scope="session"/>
<%
user.setName("一朗"); //step1
user = new User(); //step2
user.setName("二郎"); //step3
%>
step1でuserに"一朗"という名前を設定し、step2でuserに新しいオブジェクトを代入し、step3で新しいuserに"二郎"という名前を設定しています。さて、他のページでuserオブジェクトから名前を取り出すと"一朗"でしょうか、"二郎"でしょうか。答えは"一朗"です。なぜでしょう。<%
user.setName("一朗"); //step1
user = new User(); //step2
user.setName("二郎"); //step3
%>
scope="session"の指定からは、userという変数が各ページより上の階層に作られるような構造をイメージしてしまいそうですが、実際にはそうではありません。useBeanで作られたuserは、あくまで「そのページだけ」で有効な変数で、セッション上のオブジェクトへの参照がその都度コピーされるのです。つまり、隣のページのuserとは、名前が同じ別の変数なのです。これは、JSPからJavaに変換されたソース(Tomcatのworkフォルダの中にあります)を見ると分かります。上の例のuseBeanアクションは次のようなコードに展開されています。
jp.veltec.invoice.User user = null;
synchronized (session) {
user =
(jp.veltec.invoice.User) _jspx_page_context
.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
if (user == null){
user = new jp.veltec.invoice.User();
_jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
}
}
最初の行でuserという変数を宣言し、その後のブロックでセッション上に置かれたuserオブジェクトを探し(getAttribute)、見つかればその参照をuser変数に代入し、見つからなければセッション上に新たなオブジェクトを作ってその参照を代入しています。これをページごとに行っているので、useBeanでuser変数を作った後に何かを代入しても、他のページには反映されないわけです。synchronized (session) {
user =
(jp.veltec.invoice.User) _jspx_page_context
.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
if (user == null){
user = new jp.veltec.invoice.User();
_jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
}
}
しかし、セッション上のオブジェクトを入れ替えることができないわけではありません。これにはsessionオブジェクトのsetAttributeメソッドを使います。次に例を示します。
<jsp:useBean class="jp.veltec.User" id="user" scope="session"/>
<%
user.setName("一朗"); //step1
user = new User(); //step2
user.setName("二郎"); //step3
session.setAttribute("user",user);
%>
こうすれば他のページでも新しいuserオブジェクトが参照されるようになり、名前を取得すると"二郎"になります。<%
user.setName("一朗"); //step1
user = new User(); //step2
user.setName("二郎"); //step3
session.setAttribute("user",user);
%>
※実は、私自身が何度もうっかりハマっているので忘れないように書きました。
投稿:竹形 誠司[takegata]/2011年 05月 19日 06時 53分
/更新:2011年 05月 19日 07時 07分