10. タグの検証/スクリプト変数の定義
- 10.1. タグの検証
- 10.2. スクリプト変数の定義
- 10.3. TLDによるスクリプト変数の定義(JSP1.2)
10.2. スクリプト変数の定義
TagExtraInfoクラスは、タグでスクリプト変数を定義するという機能も提供しています。この機能を利用して、<jsp:useBean>アクションで新しいJava Beanを定義する事と同じような事も実現できます。スクリプト変数を定義するために行わなければならない事は以下の2つです。
- TagExtraInfoのgetVariableInfoをオーバーライドする。
- タグで作成する変数名と同じ名前で、何らかのスコープにオブジェクトを登録する。
順に説明します。TagExtraInfoのgetVariableInfoの定義は以下の通りです。
javax.servlet.jsp.tagext.VariableInfo[] getVariableInfo(javax.servlet.jsp.tagext.TagData tagData);
TagDataは検証の際と同じく、カスタムタグの属性およびその値を格納したものです。これを用いて属性の値を取得します。
VariableInfoは定義するスクリプト変数の情報を格納したものです。新たに定義する分だけVariableInfoを作成し、配列として返します。作成の際に使用するコンストラクタの定義は以下の通りです。
VariableInfo(String varName, String className, boolean declare, int scope);
「変数名」「変数の型」「変数を新たに定義するか」「変数が参照できるスコープ」を指定します。変数の型は、完全限定名でもクラス名でも、どちらでも構いません。クラス名のみで指定した場合は、タグを使用したJSPでimportされているクラスから検索されます。完全限定名で指定する方が無難でしょう。また変数の型としてクラスを指定するということは、primitive型変数の宣言はできない事を意味しています。
3番目の引数は、タグによって変数を定義するか、それともそれより前に定義されている変数を使用するかどちらかを設定します。
- trueを指定した場合には、タグによって新たに変数を定義します。タグより前に同名の変数が定義されている場合にはコンパイルエラーとなります。
- falseを指定した場合には、タグは既に定義されている変数を使用します。タグより前に使用する変数が定義されていない場合には、コンパイルエラーとなります。また定義されている変数の型が、タグで想定している方と合致しない場合にも、コンパイルエラーとなります。
「変数が参照できるスコープ」とは、定義した変数が使用できる範囲のことです。既に定義されている変数を使用する場合には、その変数の値が変更されるタイミングのことです。VariableInfoには3つのクラス変数が定義されており、これを用いてスコープを指定します。
AT_BEGIN | 開始タグ以降、JSPファイル全て |
AT_END | 終了タグ以降、JSPファイル全て |
NESTED | 開始タグと終了タグの間 |
既に定義されている変数を使用する場合には、AT_BEGINとNESTEDの違いはありません。
以下はgetVariableInfoを実装したTagExtraInfoクラスの例です。この例では、「id」という名前のObject型変数を、タグ内部で使用できるように新たに宣言しています。
import javax.servlet.jsp.tagext.TagExtraInfo; import javax.servlet.jsp.tagext.TagData; import javax.servlet.jsp.tagext.VariableInfo; public class SampleTagExtraInfo extends TagExtraInfo{ ... public VariableInfo[] getVariableInfo(TagData tagData){ VariableInfo[] variableInfo=new VariableInfo[1]; variableInfo[0]=new VariableInfo("id", "java.lang.Object", true, VariableInfo.NESTED); return(variableInfo); } }
変数の名前を、動的に決定する事も可能です。例えばある属性の値を変数名として使用する事が考えられます。しかしTagDataは実行時に決まる属性の値(スクリプトで指定される値)を取得することはできないので、その属性はスクリプト不可にする必要があります。
TagExtraInfoのgetVariableInfoメソッドのオーバーライドを完了すると、後はタグハンドラクラスでスクリプト変数に値を与えます。値を与えるには、何らかのスコープに変数の名前と同じ名前でオブジェクトを登録するのみです。先ほどの「id」変数に値を与える例です。
import javax.servlet.jsp.tagext.TagSupport; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.JspException; public class SampleTag extends TagSupport{ public int doStartTag() throws JspException{ pageContext.setAttribute("id", new Integer(100), PageContext.PAGE_SCOPE); pageContext.setAttribute("id", "text", PageContext.REQUEST_SCOPE); return(EVEL_BODY_INCLUDE); } }
複数のスコープに同名でオブジェクトが登録された場合には、page>request>session>applicationの優先順位でスクリプト変数に値が設定されます。例の場合は、pageスコープに登録されたオブジェクトがスクリプト変数の値として使用されます。またTagExtraInfoで定めたスクリプト変数の型と、スコープに登録したオブジェクトの型が異なる場合には、JSPの実行時にエラーが発生します。
(実習課題2)
実習課題1のカスタムタグを改良しなさい。
- id属性で指定した名前のスクリプト変数を定義する事。スクリプト変数のスコープはNESTEDで良い。