2.3.6 <jsp:useBean>タグのid属性重複チェック
JSP仕様では,<jsp:useBean>タグのid属性値が重複していた場合,トランスレーションエラーが発生してJSPのコンパイルに失敗します。
アプリケーションサーバでは,<jsp:useBean>タグのid属性値の重複によるトランスレーションエラーの発生を抑止して,JSPをコンパイルできます。
<jsp:useBean>タグのid属性値の重複によるトランスレーションエラーの発生を抑止した場合,次のJSPファイルの記述例のように<jsp:useBean>タグのid属性値が重複していても,JSPが問題なく動作します。
JSPファイルの記述例
(省略) : <% if (条件式){ %> <jsp:useBean id=”BeanTest” class=”test.TestClass1” /> <% } else { %> <jsp:useBean id=”BeanTest” class=”test.TestClass2” /> <% } %> : (省略)
スクリプトレットを使用して,if節とelse節にそれぞれ<jsp:useBean>タグを記述することで,片方の<jsp:useBean>タグしか実行されません。そのため,<jsp:useBean>タグのid属性値が重複していてもJSPは問題なく動作します。
<jsp:useBean>タグのid属性値の重複によるトランスレーションエラーの発生を抑止している場合に,<jsp:useBean>タグのid属性値が重複したときは,KDJE39544-Iのメッセージが出力されます。
(1) <jsp:useBean>タグのid属性重複チェックを有効にする方法
<jsp:useBean>タグのid属性値の重複によるトランスレーションエラーの発生を抑止するには,次の二つの方法があります。
-
簡易構築定義ファイルの論理J2EEサーバ(j2ee-server)の<configuration>タグ内でパラメタwebserver.jsp.translation.useBean.noCheckDuplicateIdにtrueを指定します。
簡易構築定義ファイル,および指定するパラメタの詳細については,マニュアル「アプリケーションサーバ リファレンス 定義編(サーバ定義)」の「4.3 簡易構築定義ファイル」を参照してください。
-
cjjspcコマンドに-usebeannocheckduplicateidオプションを指定してコンパイルします。
コマンドの詳細については,マニュアル「アプリケーションサーバ リファレンス コマンド編」の「cjjspc(JSPの事前コンパイル)」を参照してください。
(2) 注意事項
<jsp:useBean>タグで作成されたJavaBeansオブジェクトは,id属性値をキーにして,scope属性で指定されたスコープ内で管理されます。そのため,次の条件を満たす場合に,意図しないJavaBeansオブジェクトを取得して不正な動作となるおそれがあります。
-
<jsp:useBean>タグのid属性値の重複によるトランスレーションエラーの発生を抑止している。
-
<jsp:useBean>タグのid属性値が重複している。
-
id属性値が重複している二つ以上の<jsp:useBean>タグのclass属性に,異なるJavaBeansクラスを指定している。
<jsp:useBean>タグのid属性値の重複によるトランスレーションエラーの発生を抑止している場合に,意図したオブジェクトが取得できないおそれがあるJSPファイルの記述例について説明します。
(a) 単一のリクエストで意図しないJavaBeansオブジェクトが取得される場合のJSPファイルの記述例(二つ以上の異なる条件式で同じid属性を指定した例)
(省略) : <% if (条件式1){ %> <jsp:useBean id="BeanTest" class="test.TestClass1" scope="page"/> <% } %> <% if(条件式2) { %> <jsp:useBean id="BeanTest" class="test.TestClass2" type="test.TestIF" scope="page"/> <% } %> : (省略)
条件式1と条件式2で,id属性値に同じ値(BeanTest)が指定されています。条件式1および条件式2の両方の条件を満たす場合,一つ目の<jsp:useBean>タグでも二つ目の<jsp:useBean>タグでもtest.TestClass1クラスのオブジェクトが取得され,test.TestClass2クラスのオブジェクトは取得されません。
一つ目の<jsp:useBean>タグでid属性値「BeanTest」に対してtest.TestClass1クラスのオブジェクトが登録されます。二つ目の<jsp:useBean>タグでも同じid属性値「BeanTest」に対しての処理であると解釈されるため,一つ目の<jsp:useBean>タグで登録済みのtest.TestClass1クラスのオブジェクトが取得されます。
(b) 複数のリクエストで意図しないJavaBeansオブジェクトが取得される場合のJSPファイルの記述例1(if文とelse文で同じid属性値を指定した例)
(省略) : <% if (条件式){ %> <jsp:useBean id="BeanTest" class="test.TestClass1" scope="session"/> <% } else { %> <jsp:useBean id="BeanTest" class="test.TestClass2" scope="session"/> <% } %> : (省略)
if文とelse文で,id属性値に同じ値(BeanTest)が指定されています。リクエストを2回受け付けて,1回目のリクエストではif文の条件式が成立し,2回目のリクエストではif文の条件式が不成立となった場合,一つ目の<jsp:useBean>タグと二つ目の<jsp:useBean>タグの両方でtest.TestClass1クラスのオブジェクトが取得され,test.TestClass2クラスのオブジェクトは取得されません。
一つ目の<jsp:useBean>タグでid属性値「BeanTest」に対してtest.TestClass1クラスのオブジェクトが登録されます。二つ目の<jsp:useBean>タグでも同じid属性値「BeanTest」に対しての処理であると解釈されるため,一つ目の<jsp:useBean>タグで登録済みのtest.TestClass1クラスのオブジェクトが取得されます。
(c) 複数のリクエストで意図しないJavaBeansオブジェクトが取得される場合のJSPファイルの記述例2(<jsp:getProperty>タグまたは<jsp:setProperty>タグで,二つ以上の<jsp:useBean>タグで共通して指定されているid属性値を使用してJavaBeansオブジェクトを呼び出す例1)
(省略) : <% if (条件式1){ %> <jsp:useBean id=”BeanTest” class=”test.TestClass1” scope=”page”/> <% } %> <% if(条件式2) { %> <jsp:useBean id=”BeanTest” class=”test.TestClass2” type=” test.TestIF” scope=”page”/> <% } %> : <jsp:setProperty name=”BeanTest” property=”*”/> : <jsp:getProperty name=”BeanTest” property=”value”/> : (省略)
<jsp:getProperty>および<jsp:setProperty>タグで定義する処理では,<jsp:useBean>タグで作成されたJavaBeansオブジェクトを呼び出します。
異なるJavaBeansクラスを作成する二つ以上の<jsp:useBean>タグでid属性値を重複させると,最後に出現する<jsp:useBean>タグで指定されたオブジェクトが<jsp:getProperty>または<jsp:setProperty>タグでの処理に使用されます。
例では,条件式1と条件式2で,id属性値に同じ値(BeanTest)が指定されています。そのため,条件式1が成立する場合でも,一つ目の<jsp:useBean>タグで登録されたtest.TestClass1クラスのオブジェクトは<jsp:getProperty>および<jsp:setProperty>タグでの処理に使用されません。
(d) 複数のリクエストで意図しないJavaBeansオブジェクトが取得される場合のJSPファイルの記述例3(<jsp:getProperty>タグまたは<jsp:setProperty>タグで,二つ以上の<jsp:useBean>タグで共通して指定されているid属性値を使用してJavaBeansオブジェクトを呼び出す例2)
(省略) : <% if (条件式1){ %> <jsp:useBean id=”BeanTest” class=”test.TestClass1” scope=”page”/> : <jsp:setProperty name=”BeanTest” property=”*”/> : <jsp:getProperty name=”BeanTest” property=”value”/> : <% } %> <% if(条件式2) { %> <jsp:useBean id=”BeanTest” class=”test.TestClass2” type=” test.TestIF” scope=”page”/> : <jsp:setProperty name=”BeanTest” property=”*”/> : <jsp:getProperty name=”BeanTest” property=”value”/> : <% } %> : (省略)
<jsp:getProperty>および<jsp:setProperty>タグで定義する処理では,<jsp:useBean>タグで作成されたJavaBeansオブジェクトを呼び出します。
異なるJavaBeansクラスを作成する二つ以上の<jsp:useBean>タグでid属性値を重複させると,最後に出現する<jsp:useBean>タグで指定されたオブジェクトが<jsp:getProperty>または<jsp:setProperty>タグでの処理に使用されます。
例では,条件式1と条件式2で,id属性値に同じ値(BeanTest)が指定されています。そのため,条件式1が成立する場合でも,一つ目の<jsp:setProperty>タグでの処理に使用されるのは,二つ目の<jsp:useBean>タグで登録されたtest.TestClass2クラスのオブジェクトです。一つ目の<jsp:useBean>タグで登録されたtest.TestClass1クラスのオブジェクトは<jsp:getProperty>および<jsp:setProperty>タグでの処理に使用されません。