Java 開発者は、タグ ハンドラ、TEI クラス (オプション)、サポート クラス (オプション)、および TLD ファイルをコーディングします。また、ライブラリ内のカスタム タグの名前、タグ属性、スクリプト変数、スクリプト変数の使用法、およびスクリプト変数のスコープを文書化します。さらに、タグ ライブラリの JAR ファイルを作成し、それを WEB-INF/lib
内に配置し、必要があれば、Web アプリケーションの web.xml
ファイル内に taglib
要素をコーディングします。
タグ ハンドラおよび TEI クラスは、次のいずれかの格納場所に保存します。
WEB-INF/classes
このディレクトリは、予備段階の開発やテストを実施するときにタグ ハンドラと TEI クラスを保存するのに適しています。ただし、タグ ライブラリをパッケージ化するときは、事前にタグ ハンドラと TEI クラスを WEB-INF/lib
内の .jar
ファイルに保存しておく必要があります。
WEB-INF/lib
パッケージ化や公開を行う場合は、タグ ハンドラ、TEI クラス、およびその他の関連クラスを WEB-INF/lib
内の JAR ファイルに保存する必要があります。推奨されている TLD ファイルの配置方法など、その他のパッキング情報については、"タグ ライブラリのパッケージ化"を参照してください。
次の図に示すように、カスタム タグやタグ ライブラリをコーディングするときは、javax.servlet.jsp.tagext
パッケージ内のクラスとインターフェイスを使用します。
Tag
インターフェイス 関連する開始タグと終了タグによって呼び出される基本的な開始メソッドと終了メソッドを定義します。
BodyTag
インターフェイス カスタム タグによって本文テキストを操作する場合や、必要に応じて、結果やループを変更する場合に使用する追加メソッドを定義します。TagSupport
クラス Tag
インターフェイスを実装します。これは、本文テキストと対話しないタグ ハンドラに応じて拡張可能なヘルパ クラスです。BodyTagSupport
クラス BodyTag
インターフェイスを実装します。これは、本文テキストと対話するタグ ハンドラに応じて拡張可能なヘルパ クラスです。
タグ ライブラリのプログラミングで使用するクラスとインターフェイスの詳細については、JRun の docs
ディレクトリ内にある javadocs を参照してください。
次の例に示すように、JSP 開発者がタグ ライブラリを有効にするには、taglib
ディレクティブを使用し、prefix:tagname
の変換を使用してカスタム タグをコーディングします。
<%@ taglib prefix="test" uri="DocSamples.tld" %>
<%-- この例では、開始タグと終了タグを組み合わせます。 --%> <test:hello/>
カスタム タグ内では本文テキストを使用できますが、TLD ファイル内で本文テキストを禁止することができます。タグ ハンドラでは本文テキストと対話できます。これについては、"本文コンテンツとの対話" で説明します。
スクリプト変数と変換時属性の検証を有効にできます。これについては、"TEI クラスのコーディング"で説明します。
単純なタグ ハンドラは、親元の TagSupport
または BodyTagSupport
の doStartTag
メソッド、または必要な場合には doEndTag
メソッドを書き換えます。本文テキストとは対話しません。本文テキストとの対話がないタグ ハンドラでは、TagSupport
クラスを拡張する必要があります。TagSupport
を拡張すると、doStartTag
メソッドと doEndTag
メソッドで、定数として定義されている次の戻り値が使用されることに注意してください。
doStartTag
は、次のいずれかの値を返します。
EVAL_BODY_INCLUDE
開始タグと終了タグの間の本文テキスト (JSP コードを含む) を受け入れます。ただし、doEndTag
メソッドでは本文テキストを使用できないことに注意してください。本文テキストを評価するには、"本文コンテンツとの対話"の説明に従って BodyTagSupport
を拡張するクラスを作成します。
SKIP_BODY
本文テキストを無視します。開始タグと終了タグの間にあるテキストは評価せず、表示しません。doEndTag
は、次のいずれかの値を返します。EVAL_PAGE
ページの評価を続行します。
SKIP_PAGE
ページの残りを無視します。
次のタグ ハンドラは、doStartTag
メソッドと doEndTag
メソッドから HTML を出力します。JSP でタグ ハンドラを使用するには、TLD ファイルでタグ ハンドラを定義し、それを JSP から呼び出す必要があります。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException; public class SimpleTag extends TagSupport { /** * Executes when the tag is started. */ public int doStartTag() throws JspException { try { pageContext.getOut().print("<h2>Hello from doStartTag()</h2>"); // タグの本文でテキストを使用できるようにします。 return EVAL_BODY_INCLUDE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } /** * Executes with the end tag. */ public int doEndTag() throws JspException { try { pageContext.getOut().print("<h2>Hello from doEndTag()</h2>"); // ページの評価を継続します。 return EVAL_PAGE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } }
TLD は、タグ ライブラリを記述する XML 形式のテキスト ファイルです。JRun では、taglib
ディレクティブが含まれているページを解釈するために TLD ファイルが参照されます。taglib
ディレクティブには、TLD ファイルを指示する uri
属性が含まれています。taglib
ディレクティブの詳細については、"タグ ライブラリのパッケージ化"を参照してください。
taglib
要素は、TLD ファイルのルートです。このファイルは、次の要素から構成されています。
tlibversion
タグ ライブラリのバージョン
jspversion
(オプション) タグ ライブラリが必要とする JSP のバージョンshortname
既定のショート ネームuri
(オプション) タグ ライブラリを一意に識別する URIinfo
(オプション) タグ ライブラリの使用情報tag
カスタム タグ情報。TLD ファイルは、1 つまたは複数のタグ要素と、外部ツールで使用される 1 つの id
属性を持つことができます。それぞれの要素には、次のサブ要素が含まれています。name
: カスタム タグ名
tagclass
: タグ ハンドラのクラス名teiclass
: TEI ファイルのクラス名bodycontent
: 本文コンテンツ タイプを識別します。有効な値は、tagdependent
(SQL ステートメントなどのタグ依存本文コンテンツ)、jsp
(JSP および HTML 本文コンテンツ)、および empty
(本文コンテンツ使用不可) です。empty
を指定した場合、カスタム タグの本文は空です。info
(オプション) : カスタム タグ使用情報attribute
(オプション) : 属性情報。tag
要素は、attribute
要素を持たない場合と、1 つ以上の attribute
要素を持つ場合があります。 TLD ファイルおよび TLD の形式の詳細については、JavaServer Pages バージョン 1.1 の仕様書を参照してください。
カスタム タグは、TLD ファイル内で tag
要素とそのサブ要素によって定義します。tag
要素の主な目的は、JSP ファイルで使用されているカスタム タグ名をタグ ハンドラのクラス ファイルに関連付けることです。カスタム タグでスクリプト変数を作成する場合は、teiclass
要素を使用して、タグの TEI クラス ファイルを指定する必要もあります。
tag
要素を使用して、属性を定義することもできます。attribute
要素は必須ではありませんが、次のような場合に使用すると便利です。
attribute
要素で <required>true</required>
を指定します。
attribute
要素で <rtexprvalue>true</rtexprvalue>
を指定します。カスタム タグ属性の詳細については、"属性との対話"を参照してください。
次の TLD ファイルでは、"単純なタグ ハンドラのコーディング"で示した SimpleTag
クラスに対してタグを定義しています。
<?xml version="1.0" ?>
<taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>JRun Doc Samples</shortname> <tag> <name>hello</name> <tagclass>SimpleTag</tagclass> <bodycontent>JSP</bodycontent> </tag> </taglib>
JSP 内でカスタム タグの使用を有効にするには、taglib
ディレクティブを使用します。taglib
ディレクティブでは、タグ名と一緒に使用して特定のタグを呼び出す接頭辞を指定します。
次の JSP コードでは、TLD ファイルの例で定義されている hello
タグを呼び出しています。
<html>
<body> <h1>Simple Custom Tag</h1> <%@ taglib prefix="test" uri="DocSamples.tld" %> <test:hello/> </body> </html>
属性を受け入れるタグ ハンドラをコーディングできます。属性の機能を有効にするには、タグ ハンドラで次のことを行う必要があります。
set
で始まり、その後に先頭が大文字の変数名を付けます。たとえば、変数名が foo
であれば、setFoo
メソッドとなります。isValid
メソッドを書き換えて検証を有効にする場合は、TEI クラス内で属性を定義します。詳細については、"TEI クラスのコーディング"を参照してください。TLD ファイルの指定と TEI クラス ファイルには、強力な検証機能があります。ただし、必要な機能は、Bean に類似した setter メソッドでクラス スコープ変数と対話することだけです。たとえば、次のタグ属性の使用法を有効にするとします。
...
<test:hello username="Joe"/> ...
import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.IOException; public class TestParms extends BodyTagSupport { // 属性と同じ名前を持つオブジェクトスコープの変数です。 String username; // JSP コンパイラによって呼び出される setVariablename メソッドです。 public void setUsername(String username) { this.username = username; } // 最適な getter メソッドです。 public String getUsername() { return username; } ...
タグ ハンドラ全体を示す次の例では、JSP で提供されている include
アクション要素を属性を使用してエミュレートしています。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import javax.servlet.*; import java.io.IOException; public class TestInclude extends TagSupport { // 既定値がないので必須です。 String page; // 既定値は true です。 String flush = "true"; // setter メソッドです。 public void setPage(String page) { this.page = page; } public void setFlush(String flush) { // 小文字で保存します。 this.flush = flush.toLowerCase(); } public int doStartTag() throws JspException { // 本文テキストを無視します。 return SKIP_BODY; } // doEndTag がすべての作業を行います。 public int doEndTag() throws JspException { try { ServletContext sc = pageContext.getServletContext(); RequestDispatcher rd = sc.getRequestDispatcher(page); if (rd !=null) { // アクセス要求および応答 ServletRequest request = pageContext.getRequest(); ServletResponse response = pageContext.getResponse(); // 必要な場合は、バッファを一括消去します。 if (flush.equals("true")) { pageContext.getOut().flush(); } // ファイルをインクルードします。 rd.include(request, response); return EVAL_PAGE; } } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } catch (Exception e) { pageContext.getServletContext().log("Error with " + page, e); } return EVAL_PAGE; } }
TLD ファイル内で属性を定義するには、attribute
要素を使用します。この要素には、次のサブ要素があります。
name
属性名
required
属性が必須かどうかを示します。このサブ要素は、true
または false
に設定します。rtexprvalue
この属性の値に関する実行時式をカスタム タグで使用できるかどうかを示します。このサブ要素は、true
または false
に設定します。次の TLD エントリの例では、必須属性とオプション属性を設定しています。
<?xml version="1.0" ?>
<taglib> <tlibversion>0.0</tlibversion> <jspversion>1.0</jspversion> <shortname>test</shortname> <tag> <name>include</name> <tagclass>TestInclude</tagclass> <bodycontent>empty</bodycontent> <attribute> <name>page</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>flush</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> <tag> <name>hello</name> <tagclass>HelloTag</tagclass> <teiclass>HelloTEI</teiclass> <bodycontent>JSP</bodycontent> </tag> </taglib>
次の例に示すように、属性はカスタム タグの一部としてコーディングします。
<html>
<body> <%@ taglib prefix="test" uri="test.tld" %> <h1>Testing Custom Tags with Parameters</h1> <test:include page="/includedText.htm" flush="true" /> </body> </html>
Tag
インターフェイスと BodyTag
インターフェイスのどちらを使用しても、テンプレート テキスト、JSP スクリプト要素、およびネストしたカスタム タグをカスタム タグの本文に組み込むことができます。カスタム タグで本文コンテンツと対話しない場合は、TagSupport
クラスを拡張し、doStartTag
メソッドで EVAL_BODY_INCLUDE
を返します。一方、カスタム タグで本文コンテンツの処理、ループ、または変更が必要な場合は、doInitBody
メソッドと doAfterBody
メソッドがある BodyTagSupport
クラスを拡張します。
メモ TLD ファイル内でカスタム タグの |
BodyContent
オブジェクトは、JspWriter
のサブクラスです (JspWriter
は、JSP の out
変数のために内部的に使用されるライターです)。BodyContent
オブジェクトは、doInitBody
、doAfterBody
、およびdoEndTag
で bodyContent
変数によって使用できます。BodyContent
オブジェクトと bodyContent
変数は、大文字の使用法が違う点に注意してください。オブジェクトの内容は、doEndTag
メソッドで元の JspWriter
と統合できます。BodyContent オブジェクトには、出力を書き出すために使用するメソッドのほかに、このオブジェクトの内容の読み取り、クリア、および取り出しを行うメソッドが含まれています。たとえば、bodyContent.getString
を使用すると、ライターの内容を取り出せるほか、必要があれば、その内容を元の JspWriter
と統合する前に変更できます。
メモ
|
doAfterBody
メソッドが EVAL_BODY_TAG
を返した場合、JRun は本文の先頭に戻って再実行します。これは、一覧やデータベースの結果セットなどの反復データ全体を繰り返し処理する上で強力な機能です。
次の例は、doInitBody
メソッドと doAfterBody
メソッドの簡単な使用法を示したものです。bodyContent
の出力を出力ストリームに統合する方法も示されています。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException; public class TestBody extends BodyTagSupport { public int doStartTag() throws JspException { try { pageContext.getOut().print("<h2>We're in doStartTag()</h2>"); return EVAL_BODY_TAG; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } public void doInitBody() throws JspException { try { // これは、doStartTag や doEndTag のライターとは違うことに // 注意してください。 bodyContent.print("<h2>We're in doInitBody()</h2>"); } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } public int doAfterBody() throws JspException { try { // これは、doStartTag や doEndTag のライターとは違うことに // 注意してください。 bodyContent.print("<h2>We're in doAfterBody()</h2>"); // return EVAL_BODY_TAG; // これを使用してループします。 return SKIP_BODY; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } public int doEndTag() throws JspException { try { // bodyContent ライターから元のライターに書き込みます。 pageContext.getOut().print(bodyContent.getString()); //// バッファが大きい場合は、前の行よりも //// 次のコードの方がより効率的です。 //// 元の (囲んでいる) ライターを取得します。 // JspWriter jOut = bodyContent.getEnclosingWriter(); //// 前のライターに本文の出力を追加します。 //bodyContent.writeOut(jOut); // ここで元のライターに戻ります。 pageContext.getOut().print("<h2>We're in doEndTag()</h2>"); return EVAL_PAGE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } }
doAfterBody
が EVAL_BODY_TAG
を返すようにコーディングすることによって、カスタム タグの本文を繰り返し実行するループを作成できます。
メモ カスタム タグとループで使用されるスクリプト変数のスコープは、TEI クラスによって 制御できます。詳細については、"TEI クラスのコーディング"を参照してください。 |
次の例では、Enumeration
タイプの属性を受け入れて、Enumeration
オブジェクト内のそれぞれの名前と値 (この例では HTTP ヘッダ) をループによって処理します。
import java.util.Enumeration;
import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.IOException; public class TestBodyLoopHeaders extends BodyTagSupport { Enumeration thisEnum; public void setThisEnum(Enumeration passedEnum) { this.thisEnum = passedEnum; } public int doStartTag() throws JspException { return EVAL_BODY_TAG; } public void doInitBody() throws JspException { if (thisEnum.hasMoreElements()) { pageContext.setAttribute("nextElement", thisEnum.nextElement()); } } public int doAfterBody() throws JspException { if (thisEnum.hasMoreElements()) { pageContext.setAttribute("nextElement", thisEnum.nextElement()); return EVAL_BODY_TAG; // ループ }else { return SKIP_BODY; } } public int doEndTag() throws JspException { try { // bodyContent ライターから元のライターに書き込みます。 pageContext.getOut().print(bodyContent.getString()); return EVAL_PAGE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } }
次の JSP の例では、上記のタグ ハンドラを呼び出しています。
<html>
<body> <%@ taglib prefix="test" uri="DocSamples.tld" %> <h1>Looping through Headers</h1> <table border="1"> <tr> <th>Name</th> <th>Value</th> </tr> <test:enumloop thisEnum="<%= request.getHeaderNames() %>"> <tr> <% String header = (String)pageContext.getAttribute("nextElement");%> <td><%= header %></td> <td><%= request.getHeader(header) %></td> </tr> </test:enumloop> </table> </body> </html>
Tag
インターフェイスと BodyTag
インターフェイスのどちらを実装しているかにかかわらず、カスタム タグをネストできます。タグをネストさせると、ネストしたタグに関するタグ ハンドラでは、findAncestorWithClass
メソッドによって親クラスへの参照を取得できます。ネストしたタグ ハンドラでは、この参照を親クラスにタイプ変換することによって、親クラス内のメソッドを呼び出せます。たとえば、親クラスに実装されているメソッドを利用して、ネストしたタグ ハンドラで出力ストリームを書き出せます。
次のコードは、親タグに関するサンプル タグ ハンドラを示したものです。このサンプルには、ネストしたタグに関するタグ ハンドラで出力ストリームを更新するときに呼び出せるメソッドが含まれています。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException; public class TestBodyParent extends TagSupport { String name; public void setName(String name) { this.name = name; } public int doStartTag() throws JspException { try { // 親の名前を表示することから始めます。 pageContext.getOut().print("<h1>Parent:" + name + "</h1>"); return EVAL_BODY_INCLUDE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } public int doEndTag() throws JspException { try { // グループの後にルーラーを追加します。 pageContext.getOut().print("<hr>"); return EVAL_PAGE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } public void setNestedName(String name) throws JspException { try { // ネストされている名前を表示します。 pageContext.getOut().print("<p>Nested:" + name); } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } }
次のコードは、ネストしたタグに関するサンプル タグ ハンドラを示したものです。このサンプルでは、親のタグ ハンドラのメソッドを呼び出して、出力ストリームを更新しています。
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*; import java.io.IOException; public class TestBodyNest extends TagSupport { private String name; private TestBodyParent parent = null; public void setName(String name) { this.name = name; } public int doStartTag() throws JspException { // 親への参照を検索して保存します。 Tag t = findAncestorWithClass(this, TestBodyParent.class); if (t == null) { throw new JspException("TestBodyNest must be in TestBodyParent."); }else { parent = (TestBodyParent)t; return EVAL_BODY_INCLUDE; } } public int doEndTag() throws JspException { // 名前を親にコピーします。 parent.setNestedName(name); return EVAL_PAGE; } }
次の JSP の例では、親タグとネストしたタグを使用しています。
<html> <body> <%@ taglib prefix="test" uri="DocSamples.tld" %> <h1>Testing Nested Custom Tags</h1> <test:bodyparent name="Johnson"> <test:bodynest name="Lorna"/> <test:bodynest name="Gretchen"/> <test:bodynest name="Brian"/> </test:bodyparent> </body> </html>
カスタム タグでは、スクリプト変数を定義できます。スクリプト変数は、JSP 内のスクリプトレットやほかのカスタム タグで使用できます。
メモ スクリプト変数の定義ではタグ属性 (ID 属性など) を使用できますが、タグ属性と スクリプト変数には直接の関係はないことに注意してください。 |
JRun は、変換時に TEI クラスを使用してスクリプト変数を有効にするとともに、必要に応じて属性の検証を実行します。TEI ファイルは、TagExtraInfo
クラスを拡張する Java クラスです。getVariableInfo
メソッドには、次のシグネチャがあります。
public VariableInfo[] getVariableInfo(TagData tagData) { }
tagData
パラメータには、属性の名前/値ペアが格納されています。この名前/値ペアを使用してスクリプト変数を定義できます。たとえば、useBean
タグでは、id
属性を使用してスクリプト変数を作成しています。
getVariableInfo
メソッドで、VariableInfo
オブジェクトの配列を作成し、1 つのスクリプト変数につき 1 つの VariableInfo
オブジェクトをその配列に格納します。VariableInfo
オブジェクトのコンストラクタには、次のパラメータがあります。
varName
は、スクリプト変数名を指定する String
型パラメータです。
className
は、スクリプト変数のクラスを指定する String
型パラメータです。declare
は、コンストラクタで新規の変数を定義するかどうかを指示する boolean
型パラメータです。scope
は、スクリプト変数のスコープを指定する int
型パラメータです。このパラメータでは、次の表で示すように AT_BEGIN
、NESTED
、または AT_END
を指定します。
同期化とは、ページ コンテキストからオブジェクトを取り出して、それをスクリプト変数に代入する操作です。次の表では、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; } }
スクリプト変数を 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); // TEI ファイルによってこのスクリプト変数が // AT_BEGIN として定義されるので、ここで定義します。 // それを doInitBody 内で定義し (ループの場合)、 // doAfterBody 内で変更またはリセットできます。 pageContext.setAttribute("foo", "foo"); return EVAL_BODY_TAG; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } public void doInitBody() throws JspException { // TEI ファイルによってこのスクリプト変数が // NESTED として定義されるので、ここで定義します。 // それを doStartTag 内で定義し (ループの場合)、 // doAfterBody 内で変更またはリセットできます。 pageContext.setAttribute("baz", "baz"); } public int doEndTag() throws JspException { try { // このタグ ハンドラによって BodyTag が実装されるので // (BodyTagSupport を展開することによって)、 // 本文のライターと元のライターを統合する必要があります。 pageContext.getOut().print(bodyContent.getString()); // TEI ファイルによってこのスクリプト変数が // AT_END として定義されるので、 // doEndTag まで自分で定義する必要はありません。 pageContext.setAttribute("bar", "bar"); return EVAL_PAGE; } catch(IOException ioe) { throw new JspException(ioe.getMessage()); } } }
次の 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_TIME_VALUE
オブジェクトをチェックできます。このオブジェクトは、カスタム タグの呼び出しが実行時式を使用していることと、検証が不可能であることを示します。実行時式の詳細については、"TLD ファイルでの属性の定義"を参照してください。
次の例の TEI ファイルでは、バージョン属性の値が 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; } } }