StrutsやJSFなどのWebアプリケーションフレームワークは
全てこのJSP拡張タグライブラリによって作られています。
既存のものに満足できないあなた、是非一度自作のタグライブラリを作ってみましょう。
いきなりこんな突っこんだ所から話すのも何ですが、
これを知っておいた方がタグライブラリの製作において有利です。
JSPファイルはまず HttpServlet を継承したJavaファイルに変換されます。
Tomcatの場合、HttpJspBase の継承クラスになります。
エントリメソッドは _jspService です。
まず出力コンテキストタイプの設定、PageContextインスタンスの生成などを行います。
そしてJSPの出力を行います。
出力中に発生した全ての例外(Throwable)はcatchされ、そのまま上位にthrowされます。
この場合 web.xml で error-page の設定をしていなければ、デフォルトのエラー画面に遷移します。
JSPのコンパイルエラーが発生した場合は、画面が真っ白になり
コンソールにエラーメッセージが出力されます。
タグライブラリが一つも存在しない場合、出力メソッドは唯一です。
JSPの出力が完了すれば、このメソッドも処理を終了します。
タグライブラリを使うには、JSPの先頭でそれを宣言する必要があります。
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
各属性の意味は次の通りです。
タグライブラリに用いるタグ名を指定します。
この場合、JSP内で<c という部分を見つけると
JSPパーサがそれを拡張タグライブラリだと判断します。
原理上は html などの標準HTMLタグを指定する事も可能かもしれませんが
混乱の元になるので止めておいた方が良いでしょう。
タグライブラリの実装場所(uri)を記述します。
ただしこのuriは別名(alias)のようなもので、実際の実装ファイルは別の場所にあります。
web.xml の taglib 要素中に
uri(別名)とlocation(実際のtldファイル)の関連付けがあります。
実際にJSP内でタグライブラリを使ってみます。
ここでは ctag というprefixを使用します。
test string. <ctag:test> test string in tag. </ctag:test>
これによって生成されるJavaファイルは次のようになります。
なお、簡略化のためにメソッド名などは変えてあります。
out.write("test string\r\n");
if (_ctag_test_0(pageContent)) {
return;
}
ctag で囲まれていない部分は、通常通りwrite文で出力されます。
そして、ctag で囲まれた部分は別メソッドで処理されることになります。
では、肝心の別メソッド内を見てみましょう。
なお、説明のために若干省略してあります。
private boolean _ctag_test_0(PageContext pageContext) {
TestTag tag = _pool.get(TestTag.class);
tag.setPageContext(pageContext);
if (tag.doStartTag() != SKIP_BODY) {
do {
out.write("test string in tag.\r\n");
if (tag.doAfterBody() != EVAL_BODY_AGAIN) {
break;
}
} while (true);
}
if (tag.doEndTag() == SKIP_PAGE) {
return true;
}
return false;
}
まず、プールから TestTag クラスのインスタンスを取得します。
次に、doStartTag メソッドを呼び出します。
ここでメソッドが SKIP_BODY を返すと、ctagタグ内の評価は一切行われません。
メソッドが他の値(通常はEVAL_BODY_INCLUDE)を返すと、ctagタグ内の評価が始まります。
まずはctagタグ内をそのまま出力します。
もちろんこの中にさらに拡張タグがあれば、そのメソッドを呼び出すことになります。
そして、doAfterBody メソッドを呼び出します。
このメソッドが EVAL_BODY_AGAIN を返すと、再びタグ内を評価します。
ループ等を実装する場合に利用します。
メソッドが他の値(通常はSKIP_BODY)を返すと、タグの評価を終了します。
最後に、doEndTag メソッドを呼び出します。
このメソッドが SKIP_PAGE を返すと、trueを返して終了します。
他の値(通常はEVAL_PAGE)を返すと、falseを返して終了します。
この戻り値は呼び出し側で判断され、trueの場合はその後のJSP出力を一切行わずに
処理を完了します。このような動作はあまり使う機会は無いかもしれません。
|
|