WebLogic JSP Tag Extensions プログラマーズ ガイド
![]() |
![]() |
![]() |
![]() |
以下の節では、拡張タグの機能を実装する Java クラスを記述する方法について説明します。
JSP 1.1 API には、カスタム タグ ハンドラの作成に使用するクラスとインタフェースのセットが定義されています。javax.servlet.jsp.tagext
API についてのドキュメントは「http://java.sun.com/j2ee/j2sdkee/techdocs/api/index.html」で参照できます。
タグ ハンドラは、以下の 2 つのインタフェースのうちの 1 つを実装する必要があります。
カスタム タグが本体のないタグ (空タグ) の場合、javax.servlet.jsp.tagext.Tag
インタフェースを実装します。この API では、コンビニエンス クラス TagSupport
も提供されています。このクラスは、Tag
インタフェースを実装し、このインタフェース内で定義されているメソッド用のデフォルトの空メソッドを提供します。
Tag
インタフェースまたは BodyTag
インタフェースのどちらかから継承され、そのタグ ハンドラ クラスに実装されたメソッドは、JSP ページ処理中の特定の時点で JSP エンジンによって呼び出されます。これらのメソッドは、タグのライフ サイクルにおけるさまざまなポイントを表し、以下の順序で実行されます。
javax.servlet.jsp.tagext.Tag
インタフェースの setPageContext()
メソッドと setParent()
メソッドが呼び出されて、そのタグ ハンドラの環境コンテキストが設定されます。タグ開発者は、基本クラス TagSupport
または BodyTagSupport
を拡張する場合、これらのメソッドを実装する必要はありません。 setXXXX()
という JavaBean のようなメソッドが呼び出されます。詳細については、「タグ本体内の例外処理」を参照してください。 setBodyContent()
メソッドが呼び出されます。この時点では、タグからの出力は BodyContent
という特殊な JspWriter
にリダイレクトされ、クライアントには送られません。本体を評価して得られるすべてのコンテンツは BodyContent
バッファに追加されます。このメソッドにより、タグ ハンドラは BodyContent
バッファへの参照を格納して doAfterBody()
メソッドで評価後の処理のために使えるようにできます。 タグが出力を JSP ページ (ネスト タグの場合はその親スコープ) に渡す場合、タグはタグ ライフ サイクルのこの時点から doEndTag()
メソッドが終わるまでに、そのタグの出力を親スコープの JspWriter
に明示的に書き出す必要があります。タグ ハンドラは、getEnclosingWriter()
メソッドを使用して、親スコープの出力にアクセスできます。
コンビニエンス クラスの BodyTagSupport
を使用している場合、このメソッドを実装する必要はありません。これは、タグによって BodyContent
への参照が保持され、getBodyContent()
メソッドを介してその参照を使用できるようになるためです。
doInitBody()
メソッドが呼び出されます。このメソッドを使用すると、タグ本体が初めて評価される直前に何らかの処理を実行できます。ここでは、スクリプト変数を設定したり、タグ本体の前の BodyContent
に何らかのコンテンツを挿入したりできます。ここで付加したコンテンツは、JSP ページのタグ本体のコンテンツとは異なり、JSP として評価されることはありません。 このメソッドで実行する処理と doStartTag()
メソッドの終わりに実行する処理との大きな違いは (EVAL_BODY_TAG
を返そうとしていることが分かった場合)、このメソッドでは、タグの出力のスコープはネストされていて、JSP ページ (または親タグ) には直接向けられないということです。すべての出力は、BodyContent
という特殊な JspWriter
にバッファされます。
doAfterBody()
メソッドが呼び出されます。このメソッドは、タグの本体が評価され BodyContent
バッファに追加された後に呼び出されます。タグ ハンドラは、評価済みタグ本体に基づいて何らかの処理を行うためにこのメソッドを実装する必要があります。ハンドラがコンビニエンス クラスの BodyTagSupport
を拡張する場合、getBodyContent()
メソッドを使用して評価済みタグ本体にアクセスできます。単に BodyTag
インタフェースを実装するだけであれば、setBodyContent()
メソッドを定義して、そこに BodyContent
インスタンスへの参照を格納しておく必要があります。 この時点で、タグ ハンドラが親スコープに出力を書き出すよう指定できます。親スコープへのライターを取得するには、BodyTagSupport.getPreviousOut()
メソッドまたは BodyContent.getEnclosingWriter()
メソッドを使用します。どちらのメソッドでも、同じ親ライターが取得されます。
タグ ハンドラは評価済み本体のコンテンツを親スコープに書き出すこともあれば、その評価済み本体をさらに処理して他の何らかの出力を書き出すこともあります。本体の反復処理ごとに BodyContent
が既存の BodyContent
に追加されるので、SKIP_BODY
を返すよう決定した場合、反復処理された本体のコンテンツ全体だけを書き出します。そのようにしないと、後続の各反復処理のコンテンツが何度も出力に現れることになります。
pageContext
内の out
ライターが親の JspWriter
に復元されます。このオブジェクトは実際にはスタックであり、pushBody()
メソッドと popBody()
メソッドを使用して pageContext
上の JSP エンジンによって処理されます。ただし、タグ ハンドラの中でこれらのメソッドを使用してこのスタックを処理しようとしてはいけません。
javax.servlet.jsp.tagext.IterationTag
インタフェースを実装するタグでは、タグの本体を条件付きで再評価できる doAfterBody()
というメソッドを使用できます。doAfterBody()
が IterationTag.EVAL_BODY_AGAIN
を返す場合は、本体が再評価されます。doAFterBody()
が Tag.SKIP_BODY
を返す場合は、本体はスキップされて doEndTag()
メソッドが呼び出されます。詳細については、このインタフェースの J2EE Javadoc を参照してください (Sun Microsystems の Javadoc は、「http://java.sun.com/products/jsp/download.html」でダウンロードできます)。
注意 : IterationTag
インタフェースは、Sun Microsystems の JSP 1.2 仕様の新機能です。バージョン 1.2 は仕様の最終草案として提案されたもので、変更されることがあります。アプリケーションで JSP 1.2 の機能を使用する場合は、この仕様が最終的なものではなく、将来変更される可能性があることに注意します。
javax.servlet.jsp.tagext.TryCatchFinally
インタフェースの doCatch()
および doFinally()
メソッドを実装すると、タグ内から送出される例外を捕捉できます。詳細については、このインタフェースの J2EE Javadoc を参照してください (Sun Microsystems の Javadoc は、「http://java.sun.com/products/jsp/download.html」でダウンロードできます)。
注意 : TryCatchFinally
インタフェースは、Sun Microsystems の JSP 1.2 仕様の新機能です。バージョン 1.2 は仕様の最終草案として提案されたもので、変更されることがあります。アプリケーションで JSP 1.2 の機能を使用する場合は、この仕様が最終的なものではなく、将来変更される可能性があることに注意します。
カスタム タグでは、JSP ページから指定できる属性を何個でも定義できます。これらの属性は、タグ ハンドラに情報を渡してその動作をカスタマイズするために使用できます。
各属性名は、TLD の中で <attribute>
要素を使用して宣言します。この要素は、属性の名前とその他の属性プロパティを宣言します。
JavaBean 規約と同じように、タグ ハンドラは属性名に基づいてセッター メソッドとゲッター メソッドを実装しなければなりません。たとえば、foo
という属性を宣言する場合、タグ ハンドラは以下のパブリック メソッドを定義する必要があります。
public void setFoo(String f);
public String getFoo();
属性名の先頭の文字は、プレフィックスの set または get の後では大文字になることに注意してください。
JSP エンジンは、タグ ハンドラが初期化されてから doStartTag()
メソッドが呼び出されるまでの間に、各属性のセッター メソッドを適切に呼び出します。一般に、タグ ハンドラの他のメソッドからアクセスできるメンバー変数に属性値を格納するには、セッター メソッドを実装しなければなりません。
タグ ハンドラは、さまざまなスコープで JSP ページから参照できる新しいスクリプト変数を使用できます。スクリプト変数は、それらの定義済みスコープの内部で暗黙的なオブジェクトのように使用できます。
javax.servlet.jsp.tagext.TagExtraInfo
を拡張する Java クラスを識別するための新しいスクリプト変数は、<teiclass>
要素を使用して定義します。たとえば、次のようになります。
<teiclass>weblogic.taglib.session.ListTagExtraInfo</teiclass>
次に、TagExtraInfo
クラスを作成します。次に例を示します。
package weblogic.taglib.session;
import javax.servlet.jsp.tagext.*;
public class ListTagExtraInfo extends TagExtraInfo {
public VariableInfo[] getVariableInfo(TagData data) {
return new VariableInfo[] {
new VariableInfo("username",
"String",
true,
VariableInfo.NESTED),
new VariableInfo("dob",
"java.util.Date",
true,
VariableInfo.NESTED)
};
}
}
上の例では、VariableInfo
要素の配列を返す getVariableInfo()
というメソッドが 1 つ定義されています。各要素は、新しいスクリプト変数を定義します。上記のサンプルでは、java.lang.String
型の username
と java.util.Date
型の dob
という 2 つのスクリプト変数が定義されています。
VariableInfo()
のコンストラクタは、以下の 4 つの引数を取ります。
String
。 String
。java.lang
パッケージ以外のパッケージに含まれる型の完全パッケージ名を指定します。 boolean
。タグ ハンドラが Java 以外の言語で書かれている場合を除き、この変数は「true」に設定します。 int
。以下に示す VariableInfo
に定義されている静的フィールドを使用します。 タグ ハンドラは、ページのコンテキストを介してスクリプト変数の値を初期化しなければなりません。たとえば、上で定義したスクリプト変数の値を初期化するには、doStartTag()
メソッドの中で以下の Java ソースを使用します。
pageContext.setAttribute("name", nameStr);
pageContext.setAttribute("dob", bday);
ここで、最初のパラメータはスクリプト変数の名前を指定し、2 番目のパラメータは代入される値を示します。なお、ここでは Java 変数の nameStr
は String
型で、bday
は java.util.Date
型です。
また、TagExtraInfo
クラスを使用して作成された変数にアクセスするには、useBean
を使用して作成された JavaBean にアクセスするときと同じようにそれを参照します。
タグの属性から、新しいスクリプト変数の名前を定義できます。このように定義することで、1 つのスクリプト変数を定義するタグの複数のインスタンスを同じスコープで使用しつつ、タグのスクリプト変数名の衝突を避けることができます。TagExtraInfo
を拡張するクラスからこれを実行するには、getVariableInfo()
メソッドに渡される TagData
からスクリプト変数の名前を取得する必要があります。
TagData
からは、getAttributeString()
メソッドを使用して、スクリプト変数の名前を指定する属性の値を検索できます。さらに、id
属性の値を返す getId()
というメソッドもあります。これは、JSP タグからもたらされる新しい暗黙的オブジェクトに名前を付けるためによく使用されます。
タグ ライブラリ記述子の変数を定義できます。 Q詳細については、スクリプト変数を定義します (省略可能)を参照してください。
ネストされているタグが、その親タグに定義されているプロパティを暗黙的に使用するよう設計できます。たとえば、サンプル コードの「SQL Query」(WebLogic Server の samples/examples/jsp/tagext/sql
ディレクトリを参照) では、<sql:query>
タグが <sql:connection>
タグの内部にネストされています。query タグは親スコープの connection タグを検索して、そのタグによって確立された JDBC 接続を使用します。
親スコープのタグを見つけるために、ネスト タグは TagSupport
クラスの静的メソッドである findAncestorWithClass()
を使用します。次に、QueryTag
のサンプルから抜粋したコードを示します。
try {
ConnectionTag connTag = (ConnectionTag)
findAncestorWithClass(this,
Class.forName("weblogic.taglib.sql.ConnectionTag"));
} catch(ClassNotFoundException cnfe) {
throw new JspException("Query tag connection "+
"attribute not nested "+
"within connection tag");
}
この例では、与えられたクラスに一致するタグ ハンドラ クラスを持つ最も近い親タグ クラスが返されます。直系の親タグがこのタイプでなければ、さらにその親がチェックされます。一致するタグが見つかるまでこの処理が繰り返され、それでも見つからない場合は ClassNotFoundException
が送出されます。
カスタム タグでこの機能を使用すれば、JSP ページでのタグの構文と使い方を簡素化できます。
注意 : Java タグ ライブラリ バリデータは、Sun Microsystems の JSP 1.2 仕様の新機能です。バージョン 1.2 は仕様の最終草案として提案されたもので、変更されることがあります。アプリケーションで JSP 1.2 の機能を使用する場合は、この仕様が最終的なものではなく、将来変更される可能性があることに注意してください。
タグ ライブラリ バリデータはユーザが記述する Java クラスです。これを使用すると JSP ページ上でカスタム検証を実行できます。バリデータ クラスは入力ストリームとして JSP ページ全体を取得します。バリデータ クラスに記述した条件に基づいてページを検証できます。バリデータの一般的な使い方としては、バリデータ クラス内で XML パーサを使用して、文書型定義 (DTD) に対してページを検証する場合が挙げられます。バリデータ クラスはページの変換時 (JSP がサーブレットに変換されるとき) に呼び出され、ページが検証されると null
文字列を返します。検証が失敗するとエラー情報を含む文字列を返します。
![]() ![]() |
![]() |
![]() |