Oracle Containers for J2EE JavaServer Pages開発者ガイド 10g(10.1.3.1.0) B31860-01 |
|
この章では、カスタム・タグ、タグ・ライブラリ、およびベンダーが独自のライブラリの提供に使用できる基本的なフレームワークについて説明します。また、Oracleの拡張機能、および標準の実行時タグとベンダー固有のコンパイル時タグとの比較についても説明します。この章には、次の各項が含まれます。
この章では、タグ・ライブラリの機能の概要について説明します。詳細は、Sun社のJSP仕様を参照してください。OC4Jが提供するタグ・ライブラリについては、『Oracle Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。
カスタム・タグの作成および実装方法については、多数の資料があります。このマニュアルで説明されている以外の情報は、次の資料を参照してください。
javax.servlet.jsp.tagext
パッケージに関するSun社のJavadoc
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/package-summary.html
カスタム・タグ(タグ拡張とも呼ばれる)は、他のJavaコンポーネントによるカスタム・ロジックおよび出力をJSPページに挿入できるようにするJSP要素です。カスタム・タグを介して提供されるロジックは、タグ・ハンドラというJavaオブジェクトによって実装されます。変換時にOC4JによってJSP内のカスタム・タグが検出されると、タグ・ハンドラを取得して相互作用を行うコードが生成されます。
カスタム・タグはXML構文を使用してJSPページに含めます。タグにはボディを含めることも含めないこともできます。また、タグには、対応するタグ・ハンドラのプロパティと一致するXML属性を含めることができます。
JSP 2.0で、カスタム・タグの作成オプションは2つになりました。
タグ・ハンドラ・クラスの作成を必要とするタグには、クラシックとシンプルの2種類があります。
クラシック・タグ・ハンドラは、JSP 1.1から導入されています。クラシック・タグは、それぞれのタグに対応するタグ・ハンドラ・クラスの実装に使用するJavaインタフェースが複雑なため、作成がやや面倒です。また、動的な属性値については、Javaの式に依存します。ただし、タグ・ボディにJavaスクリプトレットまたは式を使用する場合は、これらのタグ・ハンドラを使用する必要があります。
シンプル・タグ・ハンドラはJSP 2.0で新しく導入され、クラシック・タグ・ハンドラに比べ、単純なライフサイクルとインタフェースを提供しています。タグのボディにはJSP式言語(EL)式を使用でき、まったくスクリプトを使用しないタグ開発が可能です。
JSP 2.0には、もう1つの革新的な新機能であるタグ・ファイルがあります。タグ・ファイルを使用すると、タグ・ハンドラ・クラスの作成およびコンパイルをせずに、タグ・ライブラリをJSPまたはXML構文で完全に実装できます。かわりに、タグ・ファイルはOC4J JSPコンテナによってシンプル・タグ・ハンドラに変換され、コンパイルされます。実装が容易なため、タグ・ファイルはタグ・ハンドラ作成の魅力的な代替手段となります。
関連のあるタグ・ハンドラまたはタグ・ファイルは、タグ・ライブラリとしてまとめてパッケージングできます。タグ・ハンドラとして開発されたライブラリには、タグ・ライブラリ・ディスクリプタ(TLD)というXML文書を含める必要があります。TLDは、各タグの構文を説明し、タグを対応するハンドラ・クラスにマップします。タグ・ファイル・ライブラリはTLDを必要としませんが、ライブラリをデプロイ用のアーカイブとしてパッケージングする場合はディスクリプタが必要です。
作成するカスタム・タグの種類は、必要に応じて異なります。Java言語の柔軟性が必要な場合には、クラシックまたはシンプル・タグ・ハンドラを使用するタグが理想的です。プレゼンテーションが重視されるタグを作成する場合、またはJSTLなどの既存のタグ・ライブラリを利用する場合には、タグ・ファイルが便利です。
Oracleでは、OC4Jおよびその他のコンポーネントとともに、幅広いタグ・ライブラリを提供しています。使用可能なOracleのタグ・ライブラリの詳細は、『Oracle Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。
さらに、他のタグ・ライブラリを様々なベンダーや組織から入手できます。たとえば、Jakarta Taglibsでは、幅広いライブラリをhttp://jakarta.apache.org/taglibs/
からダウンロードできます。
注意
JSTLは、OC4J内の デプロイされたWebアプリケーション間でタグ・ライブラリを共有する手順は、「Webアプリケーション間でのタグ・ライブラリの共有」を参照してください。 |
カスタム・タグには、クリーンなJSPコードやコードの再利用性を含めた、様々な利点があります。状況によっては、カスタム・タグを作成または利用することがほぼ必須になります。特に、次の場合には必要です。
JSP開発者にJavaプログラミングの経験がない場合、ページでJavaロジック(たとえば、JSP出力のプレゼンテーションとフォーマットを指示するロジック)をコーディングするのは困難な場合があります。
このような場合に、JSPタグ・ライブラリが役立ちます。出力を生成するこのようなロジックが多数のJSPページで必要な場合、Javaロジックを置換するタグ・ライブラリは、JSP開発者にとって非常に便利です。
タグ・ライブラリの提供によって、Webアプリケーションのプログラマは、サーブレットまたはJSPスクリプトレットから製品の機能や拡張機能を使用するために、Java APIに依存する必要がなくなります。タグ・ライブラリを使用すると、プログラマのタスクが大幅に軽減され、タグ・ハンドラによって適切なAPIコールが自動的に処理されます。
たとえば、OC4Jでは、電子メールとファイル・アクセス機能用に、タグとJavaBeansが提供されています。また、OC4JのWeb Object Cacheには、タグ・ライブラリとJava APIが提供されています。同様に、Oracle Application Server PersonalizationにはJava APIが提供されていますが、OC4Jにもパーソナライズ・アプリケーションをプログラミングする場合に使用できるタグ・ライブラリが提供されています。
カスタム・タグを使用するもう1つの状況は、レスポンス出力に関する特殊な実行時処理が必要な場合です。必要な機能を使用するには、処理手順を追加したり、出力をブラウザ以外の場所にリダイレクトする必要が生じる場合があります。
たとえば、タグ・テキストをブラウザではなくログ・ファイルにリダイレクトするカスタム・タグ<cust:log>
を作成できます。
<cust:log> Text to log. More text to log. Yet more text to log. </cust:log>
次の各項では、カスタム・タグを使用することにより発生する操作のセマンティクスを定義するタグ・ハンドラについて説明します。
クラシック・タグ・ハンドラは、標準のjavax.servlet.jsp.tagext.Tag
インタフェースを直接的または間接的に実装するJavaクラスのインスタンスです。クラシック・タグ・ハンドラは作成が複雑だとみなされていますが、タグ・ボディか属性値にJavaスクリプトレットまたは式を使用する場合は、これを使用する必要があります。
タグ・ボディがあるかどうか、およびボディの処理方法に応じて、タグ・ハンドラはjavax.servlet.jsp.tagext
パッケージの次のいずれかのインタフェースを実装します。
Tag
: このインタフェースは、すべてのタグを処理するための基本メソッドを定義しますが、タグ・ボディの処理は含まれません。
IterationTag
: このインタフェースは、Tag
を拡張し、タグ・ボディを反復するために使用されます。
BodyTag
: このインタフェースは、IterationTag
を拡張し、タグ・ボディ・コンテンツにアクセスするために使用されます。
クラシック・タグ・ハンドラ・クラスは、これらのインタフェースのいずれかを直接実装したり、いずれかのインタフェースを実装するクラス(Sun社が提供するサポート・クラスの1つなど)を拡張できます。
タグ・ハンドラは、必要に応じて、パラメータの受渡し、タグ・ボディの評価、およびJSPページ内の他のオブジェクト(他のタグ・ハンドラを含む)へのアクセスをサポートしています。
注意 JSP仕様では、1つのJSPページ内で同じカスタム・タグを繰り返して使用する場合に、同じタグ・ハンドラ・インスタンスを使用するか、または別のインスタンスを使用するかは指示されていません。これは、JSPベンダーが決定します。Oracle実装については、「OC4Jのタグ・ハンドラの機能」を参照してください。 |
カスタム・タグは、標準のJSPタグと同様に、ボディを使用する場合と使用しない場合があります。カスタム・タグでは、ボディを使用する場合でも、タグ・ハンドラによるボディ・コンテンツへのアクセスを必要としない場合があります。
次の4つの場合があります。
この場合、開始タグと終了タグは使用せず、単一のタグのみが使用されます。次に、一般的な例を示します。
<oracust:mytag attr="...", attr2="..." />
このコードと次のコードは同等で、いずれも使用可能です。
<oracust:mytag attr="...", attr2="..." ></oracust:abcdef>
この場合、タグ・ハンドラは、Tag
インタフェースを実装するか、またはTagSupport
を拡張する必要があります。
TLDでのこのタグの<body-content>
は、empty
に設定する必要があります。
この場合も、開始タグと終了タグの間に文のボディがありますが、タグ・ハンドラはボディを処理しません。ボディの文は、通常のJSP処理に対してのみ渡されます。次に、一般的な例を示します。
<foo:if cond="<%= ... %>" > ...body executed if cond is true, but body content not accessed by tag handler... </foo:if>
この場合、タグ・ハンドラは、Tag
インタフェースを実装する必要があります。
TLDでのこのタグの<body-content>
は、ボディ・コンテンツを変換する場合はJSP
(デフォルト)、テンプレート・データとして処理する場合はtagdependent
に設定する必要があります。
タグ・ボディが反復して処理されることを除いて、2番目の場合と同じです。
<foo:myiteratetag ... > ...body executed multiple times, according to attribute or other settings, but body content not accessed by tag handler... </foo:myiteratetag>
この場合、タグ・ハンドラは、IterationTag
インタフェースを実装する必要があります。
TLDでのこのタグの<body-content>
は、ボディ・コンテンツを変換する場合はJSP
(デフォルト)、テンプレート・データとして処理する場合はtagdependent
に設定する必要があります。
この場合も、開始タグと終了タグの間に文のボディがありますが、タグ・ハンドラはそのボディ・コンテンツにアクセスする必要があります。
<oracust:mybodytag attr="...", attr2="..." > ...body accessed and processed by tag handler... </oracust:mybodytag>
この場合、タグ・ハンドラは、BodyTag
インタフェースを実装する必要があります。
TLDでのこのタグの<body-content>
は、ボディ・コンテンツを変換する場合はJSP
(デフォルト)、テンプレート・データとして処理する場合はtagdependent
に設定する必要があります。
タグ・ハンドラによるアクセスを必要とするボディ・コンテンツを使用するカスタム・タグの場合、タグ・ハンドラ・クラスは、次の標準インタフェースを実装できます。
次の標準サポート・クラスは、BodyTag
インタフェースおよびjava.io.Serializable
インタフェースを実装し、ベース・クラスとして使用できます。
このクラスは、Tag
、IterationTag
およびBodyTag
インタフェースから適切なメソッドを実装します。
BodyTag
インタフェースは、Tag
インタフェースから基本的なタグ処理機能(doStartTag()
メソッド、doEndTag()
メソッド、およびその定義済の戻り値など)を継承します。このインタフェースは、IterationTag
インタフェースからも機能(doAfterBody()
メソッドおよびその定義済の戻り値など)を継承します。
BodyTag
インタフェースには、継承した機能の他に、タグ・ボディから実行結果を取得する機能が追加されます。タグ・ボディの評価は、javax.servlet.jsp.tagext.BodyContent
クラスのインスタンスにカプセル化されています。このインスタンスは、必要に応じて、ページ実装オブジェクトによって作成されます。
Tag
インタフェースと同様に、BodyTag
インタフェースに指定されたdoStartTag()
メソッドは、int
の戻り値としてSKIP_BODY
およびEVAL_BODY_INCLUDE
をサポートします。BodyTag
インタフェースの場合、このメソッドは、int
の戻り値としてEVAL_BODY_BUFFERED
もサポートします。次に、それぞれの値の概要を説明します。
SKIP_BODY
: ボディを評価しません。
EVAL_BODY_INCLUDE
: ボディを評価し、ボディ・コンテンツをタグ・ハンドラに対して使用可能にせずに、JSP out
オブジェクトに渡します。これは、基本的にIterationTag
インタフェースを実装するタグ・ハンドラを使用した場合のEVAL_BODY_INCLUDE
の動作と同じです。
EVAL_BODY_BUFFERED
: タグ・ボディ・コンテンツを処理するためのBodyContent
オブジェクトを作成します。
BodyTag
インタフェースには、次のメソッドの定義も追加されます。
これらの手順は、タグ・ボディが評価される前に実行されます。ボディの評価中、JSP out
オブジェクトはBodyContent
オブジェクトにバインドされます。
各ボディの評価後に、IterationTag
インタフェースを実装しているタグ・ハンドラに対して、ページ実装インスタンスはタグ・ハンドラのdoAfterBody()
メソッドをコールします。可能な戻り値は次のとおりです。
SKIP_BODY
: 反復を停止し、タグ・ボディを再評価しません。かわりに、doEndTag()
をコールします。JSP out
オブジェクトは、ページ・コンテキストからリストアされます。
EVAL_BODY_AGAIN
: 反復を継続し、タグ・ボディを再評価します。ボディは、評価時に現行のJSP out
オブジェクトに渡されます。ボディの評価後、doAfterBody()
メソッドが再度コールされます。
ボディの評価が完了しても多数の反復が必要な場合、ページ実装インスタンスは、タグ・ハンドラのdoEndTag()
メソッドを起動します。
BodyTag
インタフェースを実装しているタグ・ハンドラでは、javax.servlet.jsp.tagext.BodyContent
クラスのインスタンスを通じてタグ・ボディの評価結果にアクセスできます。このクラスは、javax.servlet.jsp.JspWriter
クラスを拡張します。
BodyContent
インスタンスは、JSPページ・コンテキストのpushBody()
メソッドを使用して作成されます。
BodyContent
オブジェクトの一般的な使用方法は、次のとおりです。
String
インスタンスに変換し、その文字列を操作の値として使用します。
out
オブジェクトに書き込みます。このオブジェクトは、開始タグが検出された時点でアクティブになっています。
シンプル・タグ・ハンドラはJSP 2.0の新機能で、クラシック・タグ・ハンドラと同様に強力な機能ですが、より単純なJavaインタフェースとより簡単なライフサイクルによって、実装がはるかに容易です。
クラシック・タグ・ハンドラと異なり、シンプル・タグ・ハンドラ・オブジェクトは、OC4J JSPコンテナによってキャッシュされたり再利用されることはありません。そのかわり、オブジェクトはインスタンス化され、実行された後に破棄されます。このインタフェースでは、キャッシュされたり再利用されるものが存在しないため、使用時に複雑なキャッシング・セマンティクスがありません。この単純化されたライフサイクルにより、タグ・ハンドラの作成が容易になり、エラーも発生しにくくなります。
ここでは、シンプル・タグ・ハンドラをJavaクラスとして実装する方法のみを説明しますが、シンプル・タグはタグ・ファイルを使用してすべてJSP構文で実装することも可能です。詳細は、「タグ・ファイルの使用」を参照してください。ただし、このオプションは、Javaの柔軟性が不要な場合のみ使用してください。
シンプル・タグ・ハンドラ・クラスは、1つのインタフェースjavax.servlet.jsp.tagext.SimpleTag
を実装します。このインタフェースに含まれるライフサイクル・メソッドは、doTag()
の1つのみです。すべての反復、ボディ評価およびその他のタグ処理は、このメソッド内で実行されます。
理想としては、シンプル・タグ・ハンドラ・クラスでjavax.servlet.jsp.tagext.SimpleTagSupport
ユーティリティ・クラスを拡張します。このクラスはSimpleTag
インタフェースを実装し、インタフェースのメソッドにデフォルトの実装を提供します。たとえば、このクラスは、ハンドラに渡されたタグ・ボディを返すgetJspBody()
を提供します。
タグ・ボディの評価はsetJspBody()
メソッドによって実行されます。このメソッドは、タグ起動のボディをカプセル化したJspFragment
オブジェクトを使用して、OC4J JSPコンテナによって起動されます。(JSPフラグメントの詳細は、「JSPフラグメントの使用」を参照してください。)タグ・ハンドラは、JspFragment
に対してinvoke()
メソッドをコールし、必要な回数だけ何度でもボディを評価できます。このように、複数回の起動および評価が可能であるという性質は、フラグメントの主要な機能です。
クラシック・タグと異なり、シンプル・タグ拡張はコール元のJSPページの基礎となるサーブレットのPageContext
に依存せず、そのかわり、PageContext
が拡張するJspContext
に依存します。JspContext
は、JspWriter
の格納やスコープ付き属性の追跡などの汎用的なサービスを提供します。一方、PageContextはサーブレットのコンテキストでのJSPのサービスに固有の機能を持っています。シンプル・タグ・ハンドラは、これらのオブジェクトを介して、JSPページから他の暗黙的なオブジェクト(request
、session
およびapplication
)を取得できます。
クラシック・タグと同様に、シンプル・タグの動作は、タグ・ハンドラ・クラスのプロパティに対応する属性を使用して制御できます。
属性には、単純、フラグメントおよび動的の3種類があります。
単純属性は、シンプル・タグ・ハンドラに渡される前に、タグの起動時に最初にOC4J JSPコンテナによって評価されます。属性は、構文attr="value"
を使用して開始タグ内で定義されます。値は、String
定数またはEL式として設定できます。
また、JSP 2.0で導入された新しい要素である<jsp:attribute>
要素を使用して、カスタム・タグのボディで属性値を定義することも可能です。次の例では、<jsp:attribute>
を使用して、<my:helloWorld>
カスタム・タグの出力を使用し、Beanオブジェクトのbar
プロパティの値を設定します。
<jsp:setProperty name="foo" property="bar"> <jsp:attribute name="value"> <my:helloWorld/> </jsp:attribute></jsp:setProperty>
フラグメント属性は、名前付きフラグメントの作成に使用されます。JSPフラグメントの概要は、「JSPフラグメントの使用」を参照してください。
動的な属性は、名前が示すとおり、タグ定義で指定されていない属性です。タグによって動的に属性を指定する機能は、JSP 2.0の新機能で、シンプル・タグ・ハンドラおよびクラシック・タグ・ハンドラの両方で使用できます。同様の方法で処理される属性が多数含まれるタグの場合、動的な属性は特に便利です。
動的な属性をサポートするタグ・ハンドラは、TLDのtag
要素でそのことを宣言する必要があります。次に例を示します。
<tag> <description> Tag that echoes all its attributes and body content </description> <name>echoAttributes</name> <tag-class>jsp2.examples.simpletag.EchoAttributesTag</tag-class> <body-content>empty</body-content> <dynamic-attributes>true</dynamic-attributes> </tag>
タグ・ハンドラ・クラスには、カスタム・タグの各属性について基礎となるプロパティがあります。このプロパティは、setterメソッドがある点などで、JavaBeanのプロパティに類似しています。
タグ属性を設定するには、次の2つの方法があります。
nrtattr="string"
リクエスト時以外の属性の場合、基礎となるタグ・ハンドラ・プロパティがString
型でないと、Webコンテナは文字列値を適切な型の値に変換しようとします。
タグ属性はBeanのプロパティに似ているため、その処理(文字列値から適切な型への変換など)もBeanのプロパティの処理に似ています。「文字列値からBeanプロパティへの変換」を参照してください。
rtattr="<%=expression%>" rtattr="${ELexpression}"
リクエスト時の属性の場合、変換は行われません。リクエスト時の式は、属性およびそれに対応するタグ・ハンドラ・プロパティ(任意のプロパティ型)に割り当てることができます。この操作は、ユーザー定義型のタグ属性などに適用できます。
カスタム・タグに明示的に定義されたオブジェクトは、そのオブジェクトのIDをハンドルとして使用して、JSPページ・コンテキストから他の操作で参照できます。次に例を示します。
<oracust:foo id="myobj" attr="..." attr2="..." />
この文によって、myobj
オブジェクトは、myobj
の宣言されたスコープに基づいて、ページ内のスクリプト要素で使用可能になります。id
属性は変換時の属性です。変数は次のいずれかの方法で指定できます。
<variable>
要素をTLDに指定し、変数の名前と型および追加情報を指定します。「TLDの<variable>要素を使用した変数宣言」を参照してください。
<tei-class>
要素に指定します。「タグ補足情報クラスを使用した変数宣言」を参照してください。
通常は、<variable>
機能を使用すると便利です。
Webコンテナによって、myobj
がページ・コンテキストに入力されます。これによって、他のタグまたはスクリプト変数は、次の構文を使用して、後でこのオブジェクトを取得できます。
<oracust:bar ref="myobj" />
このmyobj
オブジェクトは、foo
タグとbar
タグのタグ・ハンドラ・インスタンスに渡されます。ここで必要なのは、オブジェクトの名前(myobj
)のみです。
変数を作成するタグの<variable>
要素またはタグ補足情報クラスに、スクリプト変数のスコープを指定します。スコープには、次のint
定数のいずれかを指定できます。
NESTED
: スクリプト変数を定義する操作の開始タグと終了タグの間で使用可能なスクリプト変数の場合は、この設定を使用します。
AT_BEGIN
: 開始タグからそのページの最後まで使用可能なスクリプト変数の場合は、この設定を使用します。
AT_END
: 終了タグからそのページの最後まで使用可能なスクリプト変数の場合は、この設定を使用します。
JSP仕様1.1では、カスタム・タグでスクリプト変数を使用するには、タグ補足情報(TEI)クラスを作成する必要がありました。「タグ補足情報クラスを使用した変数宣言」を参照してください。JSP仕様1.2では、より簡単な方法が導入され、関連付けられたタグが定義されているTLDで<variable>
要素を使用できます。変数に関連するロジックが単純で、TEIクラスを使用する必要がない場合は、この方法で十分です。
<variable>
要素は、変数を使用するタグを定義する<tag>
要素内のサブ要素です。
変数の名前は、次のいずれかの方法で指定できます。
または
<name-given>
および<name-from-attribute>
以外に、<variable>
要素には次のサブ要素があります。
<variable-class>
要素は、変数のクラスを指定します。デフォルトはjava.lang.String
です。
<declare>
要素は、その変数が新規に宣言される変数かどうかを指定します。この場合、JSPトランスレータが変数を宣言します。デフォルトはtrue
です。false
に設定すると、変数は、標準的な機能(jsp:useBean
操作、JSPスクリプトレット、JSP宣言またはカスタム・アクションなど)を使用して、JSPページですでに宣言されているとみなされます。
<scope>
要素は、変数のスコープとして、NESTED
、AT_BEGIN
またはAT_END
のいずれかを指定します。これらの値の説明は、「スクリプト変数のスコープ」を参照してください。デフォルトはNESTED
です。
次の例では、タグmyaction
に対して2つのスクリプト変数を宣言しています。<tag>
要素内で、変数の説明に直接関係ない部分は省略されていることに注意してください。
<tag> <name>myaction</name> ... <attribute> <name>attr2</name> <required>true</required> </attribute> <variable> <name-given>foo_given</name-given> <declare>false</declare> <scope>AT_BEGIN</scope> </variable> <variable> <name-from-attribute>attr2</name-from-attribute> <variable-class>java.lang.Integer</variable-class> </variable> </tag>
最初の変数の名前は、foo_given
にハードコードされています。デフォルトで、この変数の型はString
になります。新規に宣言される変数ではなく、すでに宣言されている変数とみなされるため、そのスコープは開始タグからページの最後までとなります。
2番目の変数の名前は、必須のattr2
属性の設定に基づきます。この変数の型はInteger
です。デフォルトでは、この変数は新規に宣言され、そのスコープはNESTED
(myaction
の開始タグと終了タグの間)になります。
複雑な関連ロジックを持つスクリプト変数の場合、変数を宣言するためにTLD内で<variable>
要素を使用するだけでは不十分な場合があります。この場合は、スクリプト変数に関する詳細をjavax.servlet.jsp.tagext.TagExtraInfo
抽象クラスのサブクラスに指定できます。このマニュアルでは、このようなサブクラスをタグ補足情報クラスと呼びます。タグ補足情報クラスは、タグ属性の追加の妥当性チェックをサポートし、スクリプト変数に関する追加情報をJSP実行時機能に提供します。
Webコンテナは、タグ補足情報インスタンスを変換時に使用します。指定のタグのスクリプト変数で使用するタグ補足情報クラスは、TLDで指定します。次に、<tei-class>
要素の使用例を示します。
<tag> <name>loop</name> <tag-class>examples.ExampleLoopTag</tag-class> <tei-class>examples.ExampleLoopTagTEI</tei-class> <body-content>JSP</body-content> <description>for loop</description> <attribute> ... </attribute> ... </tag>
次に、関連クラスを示します。これらのクラスもjavax.servlet.jsp.tagext
パッケージに含まれています。
TagData
: このクラスのインスタンスには、タグ・インスタンスの変換時の属性値情報が含まれます。
VariableInfo
: このクラスの各インスタンスには、実行時にタグによって宣言、作成または変更されたスクリプト変数の情報が含まれます。
TagInfo
: このクラスのインスタンスには、関連するタグに関する情報が含まれます。クラスはTLDからインスタンス化され、変換時のみ使用できます。TagInfo
には、getTagName()
、getTagClassName()
、getBodyContent()
、getDisplayName()
およびgetInfoString()
などのメソッドがあります。
詳細は、次の場所を参照してください。
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/package-summary.html
TagExtraInfo
クラスには、次のメソッドが関連しています。
boolean isValid(TagData data)
JSPトランスレータは、このメソッドをコールして、変換時にタグ属性の妥当性チェックを実行し、TagData
インスタンスに渡します。
VariableInfo[] getVariableInfo(TagData data)
JSPトランスレータは、変換時にこのメソッドをコールして、TagData
インスタンスに渡します。このメソッドは、VariableInfo
インスタンスの配列を戻します(タグで作成されたスクリプト変数ごとに1つのインスタンスが含まれます)。
void setTagInfo(TagInfo info)
このメソッドをコールすると、TagInfo
インスタンスがタグ補足情報クラスの属性として設定されます。このメソッドは通常、Webコンテナによってコールされます。
TagInfo getTagInfo()
このメソッドを使用して、タグ補足情報クラスのTagInfo
属性を取得します。TagInfo
属性は以前に設定されていることが前提です。
タグ補足情報クラスは、スクリプト変数に関する次の情報を使用して、各VariableInfo
インスタンスを構成します。
ネストされたカスタム・タグを使用する場合、ネストされたタグのタグ・ハンドラ・インスタンスは、外部タグのタグ・ハンドラ・インスタンスにアクセスできます。これは、ネストされたタグによる処理と状態管理に役立ちます。
この機能は、javax.servlet.jsp.tagext.TagSupport
クラスの静的なfindAncestorWithClass()
メソッドを介してサポートされます。外部タグ・ハンドラ・インスタンスの名前がJSPページ・コンテキストに指定されていない場合でも、その外部タグ・ハンドラ・インスタンスは、指定したタグ・ハンドラ・クラスのインスタンスの最も近くにある、引用符で囲まれたインスタンスであるため、アクセス可能です。
次のJSPコードの例を考えてみます。
<foo:bar attr="abc" > <foo:bar2 /> </foo:bar>
bar2
タグ・ハンドラ・クラス(表記規則に従って、クラス名はBar2Tag
になります)のコード内に、次の文を含めることができます。
Tag bartag = TagSupport.findAncestorWithClass(this, BarTag.class);
findAncestorWithClass()
メソッドへの入力項目は、次のとおりです。
findAncestorWithClass()
がコールされたクラス・ハンドラ・インスタンスであるthis
オブジェクト(この例では、Bar2Tag
インスタンス)
java.lang.Class
インスタンスとしての、bar
タグ・ハンドラ・クラス(この例では、BarTag
とします)の名前
findAncestorWithClass()
メソッドは、適切なタグ・ハンドラ・クラスのインスタンスを戻します。この例では、BarTag
をjavax.servlet.jsp.tagext.Tag
インスタンスとして戻します。
これは、Bar2Tag
インスタンスでbar
タグ属性の値が必要な場合、またはBarTag
インスタンスについてのメソッドのコールが必要な場合に、Bar2Tag
が外部のBarTag
インスタンスにアクセスするために役立ちます。
Javaで実装されたクラシックまたはシンプル・タグ・ハンドラの主な作成手順は、次のとおりです。
Oracle Technology Network(OTN)のWebサイトからダウンロード可能なサンプル・アプリケーションに、シンプル・タグ・ハンドラ実装の例がいくつか含まれています。サンプル・アプリケーションをダウンロードし、OC4Jにデプロイした後、タグ・ハンドラのJavaソース・ファイルを開くと、どのように実装されているかを確認できます。
カスタム・タグごとに独自のハンドラ・クラスがあります。タグ・ハンドラ・クラス名は、表記規則によって決まります。たとえば、abc
というタグは、AbcTag
という名前になります。
タグ・ハンドラ・クラスは、PUBLICな引数のないコンストラクタを必要とします。
タグ・ハンドラ・インスタンスは、通常、JSPページ実装インスタンスによって引数が0(ゼロ)のコンストラクタを使用して作成され、リクエスト時に使用されるサーバー・サイド・オブジェクトです。タグ・ハンドラには、Webコンテナで設定されたプロパティがあります。これには、カスタム・タグを使用するJSPページのページ・コンテキスト・オブジェクトが含まれ、このタグを外部タグ内にネストして使用する場合には、タグ・ハンドラの親オブジェクトも含まれます。
タグ・ハンドラが実装するそれぞれのタグは、ハンドラ・クラスを含むタグ・ライブラリとともにパッケージングされているタグ・ライブラリ・ディスクリプタ・ファイルで定義されている必要があります。TLD内のタグ定義は、2つの役割を果します。
次のコードは、ShuffleSimpleTag
ハンドラ・クラスが含まれているライブラリのディスクリプタである、shuffle.tld
内の<my:shuffle>
タグの定義に基づいています。このハンドラは、シンプル・タグ・ハンドラの機能を示す「Random Tic-Tac-Toe」サンプル・アプリケーションに含まれています。このアプリケーションは、Oracle Technology NetworkのWebサイトからダウンロードできます。
次の例では、TLDの形式を示しています。すべてのTLDファイルは、TLDとJSPのバージョンを指定するXMLスキーマを指定している、ルートの<taglib>
要素で始める必要があります。
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/SimpleTagLibrary</uri> <tag> ... </tag> </taglib>
次に、<tag>
要素で囲まれた<my:shuffle>
タグの定義が示されます。
<tag> <name>shuffle</name> <tag-class>oracle.otnsamples.jsp20.simpletag.ShuffleSimpleTag</tag-class> <body-content>empty</body-content> <attribute> <name>fragment1</name> <required>true</required> <fragment>true</fragment> </attribute> <attribute> <name>fragment2</name> <required>true</required> <fragment>true</fragment> </attribute> <attribute> <name>fragment3</name> <required>true</required> <fragment>true</fragment> </attribute> </tag>
<tag>
要素のサブ要素によって、次のようにタグを定義します。
<name>
サブ要素は、タグの名前を指定します。
<tag-class>
サブ要素は、対応するタグ・ハンドラ・クラスの名前を指定します。タグ・ハンドラ・クラスについては、「タグ・ハンドラの使用」を参照してください。
<body-content>
サブ要素は、タグ・ボディ(ある場合)の処理方法を示します。
<variable>
サブ要素(ある場合)およびその下のサブ要素は、スクリプト変数を定義します。スクリプト変数については、「タグでのスクリプト変数の使用」を参照してください。<variable>
要素は、状況が比較的複雑ではなく、スクリプト変数のロジックでタグ補足情報クラスを必要としない場合に使用します。変数名を指定するには、名前を直接指定する場合は<name-given>
サブ要素を使用し、変数名を指定するタグ属性の名前を指定する場合は<name-from-attribute>
サブ要素を使用します。その他に、変数のクラスを指定する<variable-class>
サブ要素、変数のスコープを指定する<scope>
サブ要素、および変数が新規に定義されるものであるかどうかを指定する<declare>
サブ要素があります。詳細は、「TLDの<variable>要素を使用した変数宣言」を参照してください。<variable>
内には、オプションの<description>
要素もあります。
<tei-class>
サブ要素(ある場合)は、スクリプト変数を定義するタグ補足情報クラスの名前を指定します。これは、<variable>
要素のみでは変数を宣言できない場合に使用します。詳細は、「タグ補足情報クラスを使用した変数宣言」を参照してください。
<attribute>
サブ要素(ある場合)およびその下のサブ要素は、カスタム・タグの使用時に渡すことが可能なパラメータ(この例では指定されたフラグメント)に関する情報を提供します。<attribute>
のサブ要素には、属性名を指定する<name>
要素、属性値のJava型を示す<type>
要素(オプション)、属性が必須かどうかを指定する<required>
要素(デフォルト値はfalse
)、および属性の値として実行時の式を受け入れるかどうかを指定する<rtexprvalue>
要素(デフォルト値はfalse
)があります。例と関連情報は後述します。<attribute>
内には、オプションの<description>
要素もあります。タグ・ハンドラが含まれているタグ・ライブラリは、<taglib>
ディレクティブを使用してファイル内で参照されます。<my:...>
接頭辞は、この接頭辞を含んでいるタグが対応するTLD内で定義されていることを示します。
<%@ taglib uri="/WEB-INF/shuffle.tld" prefix="my" %>
JSP仕様1.1で最初に定義されているように、JSPページのtaglib
ディレクティブでは、特定のタグ・ライブラリを定義するTLDの名前、およびWARファイル構造における物理的な場所を完全に指定できます。次に例を示します。
<%@ taglib uri="/WEB-INF/oracustomtags/tlds/mytld.tld" prefix="oracust" %>
アプリケーションに対して相対的な場所として指定します(この例に示すように、「/
」で始まります)。アプリケーションに対して相対的な構文については、「JSPページのリクエスト」を参照してください。
TLDは、/WEB-INF
ディレクトリまたはサブディレクトリ内に含まれている必要があることに注意してください。
かわりに、JSP仕様1.1以降で定義されているように、taglib
ディレクティブは、TLDではなくJARファイルの名前、およびアプリケーション相対の物理的な場所を指定できます。JARファイルには、単一のタグ・ライブラリおよびそれを定義するTLDが含まれます。この場合、JSP仕様1.1では、TLDはJARファイル内に次のように格納され、名前が付けられる必要がありました。
META-INF/taglib.tld
JSP仕様1.1では、JARファイルは、/WEB-INF/lib
ディレクトリ内に格納する必要もありました。
次に、タブ・ライブラリJARファイルを指定するtaglib
ディレクティブの例を示します。
<%@ taglib uri="/WEB-INF/lib/mytaglib.jar" prefix="oracust" %>
複数のWebアプリケーションで共有できるようにタグ・ライブラリをパッケージングする方法を説明している、「単一のJARファイルへの複数のタグ・ライブラリとTLDのパッケージング」も参照してください。
TictactoeManual.jspページには、<my:shuffle>
タグが使用されており、これは3行、3列からなる碁盤状の表を描きます。各列には特定の色のタイルが置かれます。これは、異なる3色のタイル(またはイメージ)を持つ<my:tile>
タグをコールすることによって表示されます。これらのコールのラッピングには、<my:shuffle>
タグが使用されます。タグ・ハンドラによってランダムに3つのタイル・フラグメントが実行され、ページがロードされるたびに各行の色付きのタイルをシャッフルします。
<my:shuffle> <jsp:attribute name="fragment1"> <tr> <my:shuffle> <jsp:attribute name="fragment1"> <my:tile imageVal="../images/blue_plain.gif" /> </jsp:attribute> <jsp:attribute name="fragment2"> <my:tile imageVal="../images/yellow_plain.gif" /> </jsp:attribute> <jsp:attribute name="fragment3"> <my:tile imageVal="../images/pink_plain.gif" /> </jsp:attribute> </my:shuffle> </tr> </jsp:attribute> ... </my:shuffle>
この項では、タグ・ハンドラのプーリング、および生成コードのサイズ縮小に関するOC4JのJSP拡張機能について説明します。この項には、次の項目が含まれます。
パフォーマンスを改善するために、各JSPページ内でタグ・インスタンスを再利用するように指定できます。この機能は、タグ・プーリングとも呼ばれます。
Oracle Containers for J2EEリリース3(10.1.3)では、コンパイル時タグ・プーリング・モデルがサポートされています。タグ・ハンドラ再利用のロジックとパターンは、コンパイル時(JSPページの変換時)に決定されます。この方法は、同じページ内に多数のタグがある(たとえば、数百のタグがある)アプリケーションの場合、パフォーマンスを効率的に改善できます。
OC4J JSPコンテナでは、タグ・プーリングはtags_reuse_default
パラメータを使用して構成されます。このパラメータの設定方法の詳細は、「JSP構成パラメータの概要」を参照してください。
次のいずれかの方法で、タグ・ハンドラ再利用をコンパイル時モデルに変更できます。
tags_reuse_default
をcompiletime
に設定します。
tags_reuse_default
をcompiletime_with_release
に設定します。
compiletime_with_release
に設定すると、同じページ内で同じタグ・ハンドラが使用されるたびに、タグ・ハンドラのrelease()
メソッドがコールされます。このメソッドは、タグ・ハンドラ実装の詳細に従って、状態情報を解放します。
たとえば、タグが使用されるたびに状態情報を解放するようにタグ・ハンドラがコーディングされている場合は、compiletime_with_release
設定が適切です。タグ・ハンドラの実装、および使用するコンパイル時設定に関する詳細が不明な場合は、それぞれの値を試してください。
JSP 2.0仕様に準拠して、タグに対して定義されている属性セットが使用のたびに毎回類似している場合のみ、タグ・インスタンスを再利用できます。この制限は、compiletime
およびcompiletime-with-release
タグ・プーリング・モデルの両方に適用されます。
次の例では、JSTLのcore
ライブラリのタグを使用して、タグ・インスタンスの再利用を示しています。
<%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %> // New instance of c:forEach tag is created. // Note the inclusion of the "var" attribute. <c:forEach var='item' begin='2' end='10'> // New instance of c:out tag is created. <c:out value="foo"/> </c:forEach> <%out.println("****");%> // The first c:forEach tag instance cannot be reused, since the "var" // attribute does not exist. A new tag instance is therefore created. <c:forEach begin='1' end='10'> // The existing c:out tag instance is reused, as // the set of attributes is identical in both usages. <c:out value="bar"/>
次に、タグ・プーリングのデフォルトのcompiletime
モデルのコード・パターンを示します。
try { tag01.doStartTag(); ... tag01.doEndTag(); // reuse tag01 without calling release() tag01.doStartTag(); ... tag01.doEndTag(); } catch (Throwable e) { tag01.release(); }
次に、compiletime-with-release
オプションのコード・パターンを示します。このオプションでは、同じJSP内の同じタグ・ハンドラの使用の合間に、タグ・ハンドラ・オブジェクトに対してrelease()
メソッドをコールします。
try { tag01.setPageContext(pageContext); tag01.doStartTag(); ... tag01.doEndTag(); tag01.release(); // reuse tag01 with calling release() tag01.doStartTag(); ... tag01.doEndTag(); tag01.release(); } catch (Throwable e) { tag01.release(); }
Oracle JSP実装では、カスタム・タグを使用するための生成コードのサイズが縮小されています。また、JSP構成フラグのreduce_tag_code
をtrue
に設定すると、さらにサイズを縮小できます。
ただし、このフラグを有効にすると、タグ・ハンドラを最大限に再利用するコード生成パターンになりません。
次の各項では、タグ・ファイルの概要と詳細を説明します。
タグ・ファイルはJSP 2.0で導入され、これを使用することで、JSP作成者はJavaの知識がまったくなくても、JSP構文を使用してカスタム・タグ・ライブラリを完全に作成できます。実際のところ、タグ・ファイルの作成はJSPの作成とほぼ同じで、違いはわずかです。実装が容易なため、タグ・ファイルは従来のタグ・ハンドラに替わる魅力的な手段となります。
タグ・ファイルのソースは、JSPコードの再利用可能なフラグメントが含まれているテキスト・ファイルです。タグ・ファイルで使用できる有効なコンテンツは次のとおりです。
従来のカスタム・タグと異なり、タグ・ファイルは対応するタグ・ハンドラ・クラスを必要としません。かわりに、各ファイルはOC4J JSPコンテナによってシンプル・タグ・ハンドラに変換およびコンパイルされます。タグ・ファイルによって、Javaプログラミングの必要性がなくなり、Javaに関する詳しい作業知識を持たないJSP作成者にもタグ・ライブラリの作成が可能になります。
JSPページと同様に、タグ・ファイルでは、処理方法を指示するために標準のJSPディレクティブが使用されます。唯一の例外はpage
ディレクティブで、これは使用できません。そのかわり、タグ・ファイルでは、タグ・ファイル処理に特有の属性が含まれているtag
ディレクティブを使用します。
attribute
およびvariable
などのその他のディレクティブは、タグ・ファイルでのみ使用できます。詳細は、「タグ・ファイルでの属性の使用」および「タグ・ファイルでの変数を介したデータの公開」を参照してください。
カスタム・タグのボディの処理方法は、対応するタグ・ファイルのtag
ディレクティブのbody-content
属性で定義されます。デフォルト値はscriptless
で、前述のJSPまたは静的なテキスト要素がすべてタグ・ボディで使用できることを示します。ただし、値から推測できるとおり、Javaスクリプティング要素は使用できません。タグ・ボディを受け入れないタグは、次に示すように、empty
として宣言する必要があります。
<%@ tag body-content="empty" %>
タグのボディは、タグ・ファイル内でのみ使用可能な<jsp:doBody>
標準アクションによって評価されます。タグ・ボディ内のすべての動的なJSP要素がコールされ、生成された出力は、評価結果内のボディでテンプレート・テキストと組み合されます。
結果は変数に格納され、<jsp:doBody>
タグのvar
またはvarReader
属性を使用して指定できます。var
属性は、結果をString
として捕捉し、多くの場合に使用可能である必要があります。
varReader
属性は、結果をjava.io.Reader
オブジェクトとして捕捉します。標準またはカスタム・タグ、もしくはReader
から入力を読み込むEL関数と組み合せて使用する場合、こちらの方が効率的なことがあります。変数が指定されていない場合、出力は暗黙的なJspWriter
オブジェクトに送信されます。
SimpleTagインタフェースの説明にもあったとおり、タグ起動のボディはJspFragment
オブジェクトに変換され、これがタグ・ハンドラに渡されて処理されます。この場合、text
の値は、Webブラウザで太字および斜体フォントで表示されます。次の「タグ・ファイルでの属性の使用」で説明するとおり、フラグメントはタグ・ファイルのコンテキストで非常に便利です。
属性は、attribute
ディレクティブを使用してタグ・ファイル内で直接宣言されます。次の例では、required
属性がtrue
に設定されています。これは、ページ作成者がタグ要素のボディを渡すときにこの属性の値を指定しない場合、エラーが返されることを示します。デフォルト値はfalseです。
<%@ attribute name="category" required="true" %>
クラシックおよびシンプル・タグ・ハンドラと同様、タグ・ファイルでも、宣言されていない動的な属性を使用できます。それには、タグ・ディレクティブのdynamic-attributes
属性に、タグ起動時に渡される動的な属性の名前と値を含むマップの名前を設定します。マップには、それぞれの動的な属性の名前と値がキー/値のペアとして含まれている必要があります。
<%@ tag body-content="scriptless" dynamic-attributes="dynattrs" %>
変数もまた、variable
ディレクティブを使用してタグ・ファイル内で直接宣言されます。これは、TLD内でタグ・ハンドラによって使用される、変数を宣言するための<variable>
要素に類似しています。name-given属性は変数の名前を指定し、variable-class属性は型を定義します。
<%@ variable name-given="current" variable-class="java.lang.Object" scope="NESTED" %>
タグ・ハンドラと同様、変数のディレクティブのscope属性は、AT_BEGIN、AT_ENDまたはNESTEDの3つの値のうちの1つを受け入れます。これらは、コール元のJSPが変数を検出する場所を制御します。
タグ・ファイルはローカルのpageスコープにアクセスできます。これは、コール元のJSPのpageスコープとは異なります。異なるスコープを使用することにより、コール元のページとタグ・ファイルのpageスコープ変数に同じ名前が使用されている場合の混乱を防ぎます。多くの場合、タグ・ファイルで変数名をハードコードするのではなく、タグ・ボディで提供される属性を使用して、コール元のJSPによって変数名を指定する方が便利です。
<%@ variable name-from-attribute="var" alias="current" variable-class="java.lang.Object" scope="NESTED" %>
この例では、前の例で使用されていたname-given
属性のかわりに、name-from-attribute
およびalias
属性が使用されています。name-from-attribute
値は、変数名を提供しているタグ属性の名前です。
alias
属性値は、タグ・ファイルのローカルのpageスコープ変数の名前を宣言します。これは、OC4J JSPコンテナによってコール元のJSPのpageスコープにコピーされます。ページの作成者はカスタム・タグ内の変数に任意の名前を割り当てられますが、タグ・ファイルの開発時には固定された名前(ここではalias)が必要なため、この属性が必要になります。
JSPフラグメントは、カスタマイズされたコンテンツの作成に使用できるテンプレートとみなすことができます。JSP 2.0で導入されたJSPフラグメントは、シンプル・タグ拡張とともに使用する新しいオプションで、タグ・ファイルとシンプル・タグ・ハンドラの両方に関係があります。ただし、フラグメントの作成は、通常、タグ・ファイルのコンテキスト内で行われます。
タグ・ファイルと同様に、フラグメントは動的なJSP要素(標準のJSPアクション・タグ、カスタム・タグまたはEL式)と、タグ起動によってシンプル・タグ・ハンドラに渡されるオプションの静的なテンプレート・テキストをカプセル化したものです。
フラグメントは、必要に応じて、タグ・ハンドラによって0回以上起動および評価できます。フラグメント内のJSP要素はすべてのスコープ付き変数の現行の値にアクセスするため、通常、結果は起動のたびに異なります。これらの特性により、フラグメントは次のような場合に使用すると便利です。
タグ・ファイルで使用するための名前付きフラグメントの作成には、2段階の手順が必要です。まずタグ・ファイル内でフラグメントを宣言し、次に、カスタム・タグのボディ内の<jsp:attribute>
標準アクション・タグでボディを定義する必要があります。
フラグメントは、タグ・ファイル内でattribute
ディレクティブを使用して宣言します。ディレクティブのfragment
属性をtrue
に設定すると、フラグメントはタグ・ハンドラによって評価されます。デフォルトの設定false
では、属性をタグ・ハンドラに渡す前にOC4J JSPコンテナで評価するように強制します。これにより、フラグメントを0回以上評価することが可能になります。
<%@ attribute name="frag1" fragment="true" %> <%@ attribute name="frag2" fragment="true" %>
次に、JSP構文を使用して、タグ・ファイル内の関連付けられたロジックを定義します。次のタグ・ファイルのコードは、JSTLタグを使用して実装された条件付きロジックを示します。テストの評価がtrueの場合、frag1
が起動されます。
<c:when test="${empRow[2] >= 10000}"> <c:set var="name" value="${empRow[0]}"/> <c:set var="phone" value="${empRow[1]}"/> <c:set var="salary" value="${empRow[2]}"/> <jsp:invoke fragment="frag1"/> </c:when>
フラグメントは、タグ・ファイル内の<jsp:invoke>
標準アクション・タグを使用して、名前で起動されます。<jsp:doBody>
と同様に、このアクションはタグ・ファイル内でのみ使用できます。タグ・ボディ内のスコープ付き変数(この場合はEL演算子)はタグ・ファイルによって設定されるため、起動のたびにフラグメントをタグ・ファイル・コードによってカスタマイズすることが可能になります。
フラグメントのコンテンツは、前述のとおりJSP要素と静的なHTMLで構成され、カスタム・タグのボディ内の<jsp:attribute>
標準アクション・タグのボディ内で定義されます。
<tags:EmpDetails deptNum="80"> <jsp:attribute name="fragment1"> <tr bgcolor="#FFFF99" align="center"> <td><font color="#CC0033">${name}</font></td> <td><font color="#CC0033">${phone}</font></td> <td><font color="#CC0033">${salary}</font></td> </tr> </jsp:attribute> </tags:EmpDetails>
次に、タグ・ボディの評価の結果を格納するvar
属性の使用方法を表した単純な例を示します。
サンプルのdoBodyVarTest.tag
ファイルは、Example.jsp
内の<tags:doBodyVarTest>
タグのボディの評価結果を格納するtext
という名前の変数を定義します。また、EL変数の評価結果を格納するfrag1
とfrag2
という2つのフラグメント属性も定義します。
タグ・ファイルが実行されると、Webコンテナにより、フラグメント属性とタグ・ボディという2種類のフラグメントがタグ・ファイルに渡されます。タグ・ファイル内では、<jsp:invoke>
要素を使用してフラグメント属性が評価され、<jsp:doBody>
要素を使用してタグ・ファイルのボディが評価されます。それぞれの種類のフラグメントの評価結果は、レスポンスに送信されるか、または後の操作のためにEL変数に格納されます。
<%@ attribute name="frag1" required="true" fragment="true" %> <%@ attribute name="frag2" required="true" fragment="true" %> <%@ variable name-given="text" scope="NESTED" %> <jsp:doBody var="text" /> <TABLE border="0"> <TR> <TD> <b><jsp:invoke fragment="frag1"/></b> </TD> </TR> <TR> <TD> <i><jsp:invoke fragment="frag2"/></i> </TD> </TR> </TABLE>
Example.jsp
コードにより、doBodyVarTest
タグのインスタンスが作成されます。<jsp:body>
タグには、タグ・ハンドラによってtext
変数に設定される文字列が含まれています。<jsp:body>
タグは、シンプル・タグのボディを明示的に指定するために使用されます。また、タグ起動のボディに1つ以上の<jsp:attribute>
要素が使用される場合、タグ・ボディの指定に使用できるのはこのタグのみです。
<%@ taglib tagdir="/WEB-INF/tags" prefix="tags" %> <html> <body> <tags:doBodyVarTest> <jsp:attribute name="frag1"> ${text} </jsp:attribute> <jsp:attribute name="frag2"> ${text} </jsp:attribute> <jsp:body> Have a great day! </jsp:body> </tags:doBodyVarTest> </body> </html>
タグ・ライブラリをタグ・ファイルとして実装する手順は簡単です。この章で概要が説明されているとおりにタグ・ファイルを作成するのみです。
この章で前述したとおり、タグ・ファイルの作成はJSPの作成と非常に似ています。タグ・ファイルで使用できる要素のサマリーは、「タグ・ファイルとは」を参照してください。
JARファイル内のタグ・ファイルはコンパイルされていないタグ・ファイルとして残るため、誰でもテキスト・エディタを使用してコードを参照できる点に注意してください。
タグ・ファイルは次のいずれかの方法でデプロイできます。
/WEB-INF/tags
ディレクトリに、タグを直接ドロップします。 この方法でデプロイされた場合、タグ・ファイルはタグ・ライブラリ・ディスクリプタを必要としません。ただし、他のアプリケーションの/WEB-INF/tags
ディレクトリにもタグをコピーしないかぎり、タグはそのアプリケーションからのみアクセス可能です。
この方法でタグ・ファイルをパッケージングするには、TLDが必要です。TLDで定義されていないJAR内のタグ・ファイルは、OC4J JSPコンテナによって無視されます。
JARにパッケージングされると、タグ・ファイルはJAR内の/META-INF/tags
の下に追加されます。その後、JARはWebアプリケーションの/WEB-INF/lib/
ディレクトリにインストールされます。
JAR内の各タグ・ファイルは、TLDの<tag-file>
要素内で定義されます。これは、クラシックまたはシンプル・タグ・ハンドラの定義に使用される<tag>
要素と異なります。それぞれの<tag-file>
要素は2つのサブ要素を取ります。
次の例は、配置用にJARにパッケージングされた2つのタグ・ファイルを定義するTLDを示しています。
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>MyTagFiles</short-name <uri>/MyTagFiles</uri> <description>JSP 2.0 tag files</description> <tlib-version>1.0</tlib-version> <short-name>My Tag Files</short-name> <tag-file> <name>EmpDetails</name> <path>/META-INF/tags/mytags/EmpDetails.tag</path> </tag-file> <tag-file> <name>ProductDetails</name> <path>/META-INF/tags/mytags/ProductDetails.tag</path> </tag-file> </taglib
JSPページは、taglib
ディレクティブを使用して、タグ・ファイルが実装されたタグ・ライブラリをインポートします。タグ・ライブラリの接頭辞は、prefix
属性を使用して指定されます。ただし、これ以外に含まれる属性は、タグ・ファイルのデプロイ方法によって異なります。
タグ・ファイルがJARにパッケージングされていない場合、tagdir
属性の値には、タグ・ファイルが格納されているディレクトリへのコンテキスト相対パスを設定する必要があります。
<%@ taglib tagdir="/WEB-INF/tags/mytags" prefix="mytags" %>
タグ・ファイルがJARにパッケージングされている場合、uri
属性が使用され、TLD内の<uri>
要素のコンテンツが設定されます。
<%@ taglib uri="/MyTagFiles" prefix="mytags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
次の各項では、タグ・ライブラリとTLDのパッケージング、格納およびアクセスについて説明します。
JSP仕様では、単一のJARファイル内に、複数のタグ・ライブラリおよびタグ・ライブラリを定義するTLDをパッケージングできます。
この項では、複数のタグ・ライブラリを単一のJARファイルにパッケージングする例を示します。JARファイルには、タグ・ハンドラ・クラス、タグ・ライブラリ・バリデータ(TLV)クラス、および複数のライブラリのTLDが含まれています。
次に、JARファイルの内容と構造を示します。複数のTLDが含まれているJARファイル内では、TLDは/META-INF
ディレクトリまたはサブディレクトリ内に格納されている必要があります。
examples/BasicTagParent.class examples/ExampleLoopTag.class examples/BasicTagChild.class examples/BasicTagTLV.class examples/TagElemFilter.class examples/TagFilter.class examples/XMLViewTag.class examples/XMLViewTagTLV.class META-INF/xmlview.tld META-INF/exampletag.tld META-INF/basic.tld META-INF/MANIFEST.MF
複数のTLDが含まれたJARファイルは、/WEB-INF/lib
ディレクトリ内、またはOC4Jの予約済のタグ・ライブラリの場所(「予約済のタグ・ライブラリの場所の指定」を参照)に格納する必要があります。JSPコンテナは、変換時に、この2つの場所でJARファイルを検索し、各JARファイルでTLDを検索し、各TLDにアクセスして<uri>
要素を検索します。
各TLDには、<taglib>
要素内に<uri>
要素があります。この機能は、次のように使用します。
<uri>
要素に指定する値は、対応するタグ・ライブラリを使用するJSPページ内で、taglib
ディレクティブのuri
設定と一致する値であることが必要です。
<uri>
の各値は、サーバー上のすべてのTLD内にある<uri>
の値の中で一意であることが必要です。
<uri>
要素には任意の値を設定できますが、XML名前空間の規則に従って設定する必要があります。この値はキーとしてのみ使用され、物理的な場所を示しません。ただし、表記規則上、値は物理的な場所と同じ形式になります。
basic.tld
ファイルには次の内容が含まれます。
<taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>basic</short-name> <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld</uri> ... </taglib>
exampletag.tld
ファイルには次の内容が含まれます。
<taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>example</short-name> <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld</uri> ... </taglib>
xmlview.tld
ファイルには次の内容が含まれます。
<taglib> ... <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>demo</short-name> <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld</uri> ... </taglib
この項では、web.xml
デプロイメント・ディスクリプタの<taglib>
要素を示します。この要素は、URIのすべての値(前項で説明したTLDの<uri>
要素)を、ライブラリにアクセスするJSPページで使用するショートカットURI値にマッピングします。
<taglib>
要素には、2つのサブ要素を含めることができます。
<taglib-uri>
タグを使用するJSPページ内のtaglib
ディレクティブのuri
属性の値として使用されるショートカットURIが含まれます。
<taglib-location>
タグ・ライブラリの一意の識別子が含まれます。この場合、<taglib-location>
値は実際には場所ではなくキーを示し、任意のタグ・ライブラリのTLDにある<uri>
値に対応します。
各TLD、または単一のタグ・ライブラリとそのTLDが含まれるJARファイルを使用する場合、<taglib-location>
サブ要素は、TLDまたはタグ・ライブラリJARファイルの、アプリケーション相対の物理的な場所(「/
」で始まります)を示します。関連情報は、「予約済のタグ・ライブラリの場所の指定」を参照してください。
複数のタグ・ライブラリとそのTLDが含まれるJARファイルを使用する場合、<taglib-location>
サブ要素は、タグ・ライブラリの一意の識別子を示します。この場合、<taglib-location>
値は実際には場所ではなくキーを示し、任意のタグ・ライブラリのTLDにある<uri>
値に対応します。関連情報は、「単一のJARファイルへの複数のタグ・ライブラリとTLDのパッケージング」を参照してください。
<taglib> <taglib-uri>/oraloop</taglib-uri> <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld </taglib-location> </taglib> <taglib> <taglib-uri>/orabasic</taglib-uri> <taglib-location> http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld </taglib-location> </taglib> <taglib> <taglib-uri>/oraxmlview</taglib-uri> <taglib-location> http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld </taglib-location> </taglib>
この項では、適切なtaglib
ディレクティブを示します。このディレクティブは、前項でリストされているweb.xml
要素に定義されたショートカットURI値を参照します。
ページbasic1.jsp
には、次のディレクティブが含まれます。
<%@ taglib prefix="basic" uri="/orabasic" %>
ページexampletag.jsp
には、次のディレクティブが含まれます。
<%@ taglib prefix="example" uri="/oraloop" %>
ページxmlview.jsp
には、次のディレクティブが含まれます。
<%@ taglib prefix="demo" uri="/oraxmlview" %>
JSP仕様で規定されている標準的な予約済URI機能の拡張機能として、OC4Jは、予約済のタグ・ライブラリの場所と呼ばれる1つ以上のディレクトリの使用をサポートします。このディレクトリには、複数のWebアプリケーション間で共有するタグ・ライブラリJARファイルを格納できます。
デフォルトの予約済のタグ・ライブラリの場所は、ORACLE_HOME
/j2ee/home/jsp/lib/taglib/
ディレクトリです。この場所にインストールされたタグ・ライブラリは、デフォルトで、OC4JインスタンスにデプロイされたすべてのWebアプリケーションで使用可能になります。
また、共有タグ・ライブラリの場所を追加で定義し、これらのディレクトリに、アプリケーション間で共有するタグ・ライブラリJARファイルをインストールできます。予約済のタグ・ライブラリの場所の定義には、2つの手順が必要になります。
ORACLE_HOME
/j2ee/home/config/global-web-application.xml
ファイルの<orion-web-app>
要素のjsp-taglib-locations
属性で定義します。それぞれの場所は、セミコロンで区切ります。
<library>
要素をORACLE_HOME
/j2ee/home/config/application.xml
に追加します。これは、default
アプリケーションの構成ファイルです。path
属性を、タグ・ライブラリJARファイルが含まれているディレクトリに設定します。
複数の共有タグ・ライブラリの場所を指定および利用できるかどうかは、
重要
<orion-web-app>
要素のjsp-cache-tlds
属性の値によって決定されます。詳細は、表7-1「TLDキャッシングのパラメータ」を参照してください。
共有タグ・ライブラリのサポートの一環として、OC4JではTLDの永続的なキャッシング機能を提供しています。これには、すべての予約済のタグ・ライブラリの場所におけるTLDのグローバル・キャッシュ、およびTLDキャッシングを使用するアプリケーションに対するアプリケーション・レベルでのキャッシュが含まれます。
TLDキャッシングの使用により、アプリケーションの起動時やJSPページ変換時のパフォーマンス速度が向上します。ただし、次の状況では、TLDキャッシングをオフにしてください。
TLDキャッシングは、<orion-web-app>
要素のjsp-cache-tlds
属性によって有効化または無効化されます。
global-web-application.xml
ファイルのこの属性で設定されます。このファイルで設定された値は、OC4Jインスタンスにデプロイされた他のすべてのWebアプリケーションによって継承されるデフォルト値になります。
orion-web.xml
ファイルで設定されます。このファイルの設定は、global-web-application.xml
のデフォルト設定をオーバーライドします。
次の表で、jsp-cache-tlds
属性の値のサマリーを示します。
jsp-cache-tldsの値 | global-web-application.xmlで設定される値 |
---|---|
|
TLDキャッシングは有効です。これは、グローバル・レベルおよびアプリケーション・レベルでのデフォルト設定です。
タグ・ライブラリJARをデフォルトの予約済のタグ・ライブラリの場所である
TLD( |
|
タグ・ライブラリが含まれているJARファイルを次のいずれかに追加します。
|
|
タグ・ライブラリJARをデフォルトの予約済のタグ・ライブラリの場所である
異なる場所を、
初期化パラメータは、このファイルの |
TLDキャッシングを使用するアプリケーションの場合、グローバル・レベルまたはアプリケーション・レベルで有効になっているかどうかに関係なく、2つのレベルのキャッシングがあり、各レベルのキャッシングには2つの機能があります。
キャッシング・レベル:
/WEB-INF
ディレクトリにあります。 アプリケーション・レベルでは、タグ・ライブラリJARファイルにはTLDが含まれており、/WEB-INF/lib
ディレクトリ内に格納する必要があります。
個別のTLDは、/WEB-INF
内のディレクトリに直接、または任意のサブディレクトリに格納できますが、できれば、/WEB-INF/lib
または/WEB-INF/classes
には格納しないでください。<orion-web-app>
要素のjsp-cache-tlds
属性がstandard
に設定されている場合、TLDを/WEB-INF/lib
または/WEB-INF/classes
のいずれにも格納しないでください。
各レベルのキャッシング機能:
/WEB-INF
または/WEB-INF/lib
です。この機能によって、JARファイルを複数回スキャンする必要はありません。JARファイルには、2つのタイプのエントリがあります。
グローバル・キャッシュは、構成ディレクトリと並列の、tldcache
というディレクトリに常に格納されます。tldcache
ディレクトリには、次のものが含まれます。
_GlobalTldCache
ファイル。前述のように、予約済の場所に関するリソース情報が含まれています。
ojsputil.jar
にemail.tld
がある場合、DOM表現は次のファイル(ディレクトリojsputil_jar
のファイル名email
)に格納されます。
ORACLE_HOME/j2ee/home/jsp/lib/taglib/persistence/ojsputil_jar/email
これは、Oracle Application Server環境で、ORACLE_HOME
が定義されている場合です。スタンドアロンOC4Jでは、j2ee
ディレクトリは、OC4Jがインストールされた場所に対する相対パスになります。
アプリケーション・レベルのキャッシュは、global-web-application.xml
またはorion-web.xml
のjsp-cache-directory
設定で指定されたディレクトリに格納されます。このディレクトリには、次のものが含まれます。
_TldCache
ファイル。前述のように、/WEB-INF
ディレクトリのTLDに関するリソース情報が含まれています。/WEB-INF/lib
のJARファイル内、または/WEB-INF
や任意のサブディレクトリに個別に格納されますが、できれば、/WEB-INF/lib
または/WEB-INF/classes
は使用しないでください。 <orion-web-app>
要素のjsp-cache-tlds
属性がstandard
に設定されている場合、TLDを/WEB-INF/lib
または/WEB-INF/classes
のいずれにも格納しないでください。
/WEB-INF
のTLDのDOM表現。/WEB-INF/lib
ディレクトリのJARファイルに格納されているTLDの場合、DOM表現は、グローバル・キャッシュについて説明したものと同じスキーム・タイプで、jsp-cache-directory
で指定されたディレクトリのサブディレクトリに格納されます。/WEB-INF
の個別のTLDの場合、DOM表現は、jsp-cache-directory
の場所に直接格納されます。
|
![]() Copyright © 2007 Oracle Corporation. All Rights Reserved. |
|