スクリプト変数は、ユーザーがページをリクエストするときに JSP で使用できる変数です。宣言、スクリプトレット、または式の中のスクリプト変数にアクセスできます。
カスタムタグでスクリプト変数を定義できます。スクリプト変数は、JSP 内のスクリプトレットや他のカスタムタグで使用できます。スクリプト変数は、JSP の pageContext オブジェクトにオブジェクトとして保管されます。その結果、スクリプト変数を Strings および Integers として設定できるだけでなく、データベース接続または他の直列化可能なオブジェクトとしても設定できます。
カスタムタグにスクリプト変数を設定するには、2 つの方法があります。
variable
要素を追加する必要があります。どちらの方法でも、JSP でカスタムタグスクリプト変数を使用可能にできますが、JSP 1.2 の方法の方が簡単に実装できます。ただし、多くの既存のカスタムタグライブラリでは JSP 1.1 の方法を使用しているので、JSP 1.1 の方が柔軟性はあります。
このセクションでは、カスタムタグ内でスクリプト変数を使用する 2 つの方法を説明します。
メモ: タグ属性 (ID 属性など) を使用してスクリプト変数を定義できますが、タグ属性とスクリプト変数は直接は関係ありません。
JSP 1.2 では、JSP ページのカスタムタグのスクリプト変数を使用する簡単な方法を導入しています。次のタスクを実行する必要があります。
variable
要素を追加します。
タグハンドラは pageContext オブジェクトにスクリプト変数を追加します。タグハンドラでは、スクリプト変数に指定されているスコープに応じて、これらの変数をさまざまな方法で定義します。さらに、本文テキストをループ処理するタグハンドラでは、doAfterBody
メソッドによって、スクリプト変数を更新またはリセットできます。
次の例は、タグハンドラがスクリプト変数を設定する方法を示しています。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException;
public class HelloTag extends BodyTagSupport {
String to;
public void setTo(String to) {
this.to = to; }
public int doStartTag() throws JspException {
try { pageContext.getOut().print("Hello " + to);
// AT_BEGIN として定義されるので、ここで定義します。
// doInitBody 内で定義し、ループの場合は // doAfterBody 内で変更またはリセットできます。 pageContext.setAttribute("foo", "foo"); return EVAL_BODY_INCLUDE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } }
public void doInitBody() throws JspException {
// NESTED として定義されるので、ここで定義します。 // doStartTag 内で定義し、ループの場合は // doAfterBody 内で変更またはリセットできます。 pageContext.setAttribute("baz", "baz"); }
public int doEndTag() throws JspException {
try { // このタグハンドラによって BodyTag が実装されるので // (BodyTagSupport を拡張することによって)、 // 本文のライターと元のライターを統合する必要があります。 pageContext.getOut().print(bodyContent.getString());
// AT_END として定義されるので、
// doEndTag まで自分で定義する必要はありません。 pageContext.setAttribute("bar", "bar"); return EVAL_PAGE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } }
tag
要素の variable
サブ要素にスクリプト変数を定義します。次の表で、variable
要素のサブ要素について説明します。
次の例は、カスタムタグのスクリプト変数を定義する TLD ファイルを示しています。
<?xml version="1.0" ?>
<taglib> ... <tag> ... <variable> <name-given>foo</name-given> <name-from-attribute>foo</name-from-attribute> <variable-class>java.lang.String</variable-class> <declare>true</declare> <scope>AT_BEGIN</scope> </variable> <variable> <name-given>bar</name-given> <name-from-attribute>bar</name-from-attribute> <variable-class>java.lang.String</variable-class> <declare>true</declare> <scope>AT_END</scope> </variable> <variable> <name-given>baz</name-given> <name-from-attribute>baz</name-from-attribute> <variable-class>java.lang.String</variable-class> <declare>true</declare> <scope>NESTED</scope> </variable> ... </tag> </taglib>
JSP 1.1 で JSP ページのカスタムタグのスクリプト変数を使用するには、次のタスクを実行する必要があります。
このセクションで説明した JSP 1.1 の方法でスクリプト変数を使用すれば、TEI クラスを拡張することによってタグを検証できます。このようなタグの検証が不要な場合は、 「JSP 1.2 でのスクリプト変数の使用」 で説明した JSP 1.2 の方法でスクリプト変数を使用します。
カスタムタグでスクリプト変数を作成する場合、Java 開発者は TEI ファイルも作成する必要があります。TEI ファイルは、JSP コードで使用するスクリプト変数とそのスコープを定義する Java クラスです。TEI ファイルを使用して、トランスレート時に属性を検証することもできます。
TEI ファイルは、TagExtraInfo
クラスを拡張する Java クラスです。getVariableInfo
メソッドには、次の署名があります。
public VariableInfo[] getVariableInfo(TagData tagData) { }
tagData
パラメータには、属性の名前/値のペアが格納されています。この名前/値のペアを使用してスクリプト変数を定義します。たとえば、useBean
タグは、id
属性を使用してスクリプト変数を作成します。
getVariableInfo
メソッド内で、VariableInfo オブジェクトの配列を作成し、1 つのスクリプト変数につき 1 つの VariableInfo オブジェクトをその配列に挿入します。次の表で、VariableInfo オブジェクトのコンストラクタが取るパラメータについて説明します。
同期化とは、ページコンテキストからオブジェクトを取り出して、それをスクリプト変数に割り当てる操作です。次の表で、getVariableInfo
メソッドで指定した変数に関するスコープ、使用方法、および同期化について説明します。
次の例は、3 つのスクリプト変数を定義する TEI クラスに関する Java コードを示しています。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException;
public class HelloTEI extends TagExtraInfo {
public VariableInfo[] getVariableInfo(TagData tagData) { VariableInfo[] vars = new VariableInfo[3];
// ページの本文と残りの部分で使用できます。
vars[0] = new VariableInfo("foo", "java.lang.String", false, variableInfo.AT_BEGIN);
// ページの残りの部分のカスタムタグの後ろで使用できます。
vars[1] = new VariableInfo("bar", "java.lang.String", true, VariableInfo.AT_END);
// タグ本文でのみ使用できます。
vars[2] = new VariableInfo("baz", "java.lang.String", true, VariableInfo.NESTED); return vars; } }
次の JSP の例では、TEI クラスで定義したスクリプト変数を使用しています。
<%@ taglib prefix="test" uri="test.tld" %>
<% String foo; %>
<test:hello to="World">
<%-- baz は NESTED です (本文でのみ使用可能)。--%> <%= baz %> <%-- foo は AT_BEGIN です (本文とそれ以外でも使用可能)。--%> <%= foo %> </test:hello> <%= foo %> <%-- bar は AT_END です (本文の後ろでのみ使用可能)。--%> <%= bar %>
TEI クラスは、isValid
メソッドをオーバーライドしてタグ特有の属性の検証を実施できます。トランスレート時に、JRun から isValid
メソッドに TagData
インスタンスが渡されます。
isValid
メソッドは、TagData.getAttribute
を呼び出して、その値にアクセスできます。TLD ファイル内の属性の定義で実行時の式を有効にしている場合は、TagData.REQUEST_
オブジェクトを調べることができます。このオブジェクトは、カスタムタグの呼び出しが実行時の式を使用していることと、検証が不可能であることを示します。実行時の式の詳細については、 「TLD ファイルでの属性の定義」 を参照してください。
TIME_VALUE
次のクラスの例では、バージョン属性の値が 5 より小さいことを確認します。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException;
public class TestIsValidTEI extends TagExtraInfo {
// この例では、スクリプト変数が 1 つであると想定しています // (この例とは無関係)。
public VariableInfo[] getVariableInfo(TagData tagData) {
VariableInfo[] vars = new VariableInfo[1]; vars[0] = new VariableInfo("foo", "java.lang.String", true, VariableInfo.AT_BEGIN); return vars; }
public boolean isValid(TagData data) {
Object version = data.getAttribute("version"); // この属性では実行時の式が使用できるので、 // REQUEST_TIME_VALUE をチェックする必要があります。 if (version != null && version != TagData.REQUEST_TIME_VALUE) { int iVersion = Integer.parseInt((String)version); // バージョンは 5 以下です。 if (iVersion > 5) { return false; }else { return true; } }else { return false; } } }