SimpleTagSupportの働き
ここでは、Java 6からサポートされた元号を使って今日の日付を作成し表示するタグを定義してあります(それ以前のものをお使いの場合は、Locale.setDefaultするLocaleを一般的なLocaleで指定してください)。今回は「SimpleTagSupport」というクラスを継承して利用しています。これは、タグ用に用意されているクラスの中でも最もシンプルなものです。
「SimpleTagSupport」クラスにはdoTag
というメソッドが用意されています。JSPのソースコード内に記述されているタグ部分が読み込まれ、タグが呼び出されると、このdoTag
メソッドが実行されます。
このdoTag
で行っているのは、「Calendar」と「SimpleDateFormat」を使って日付のStringを作成し、これをタグの利用元であるJSP側に出力するという処理です。ここでのポイントは、以下の部分です。
JspWriter out = this.getJspContext().getOut();
this(SimpleTagSupportクラス)には、getJspContext
というメソッドが用意されています。これは、「JspContext」というクラスのインスタンスを返すものです。JspContextは、タグが埋め込まれているJSPのコンテキストを管理しており、ここからJSPに関する機能を利用します。
JSPへの出力は、このJspContextのgetOut
メソッドを呼び出して得られるJspWriterというクラスのインスタンスを利用します。これは、文字通りJSPの出力用のOutputStreamです。これを取得し、そこに用意されている出力メソッドを使ってテキストを書き出します。
out.println("<strong>"); out.println(format.format(cal.getTime())); out.println("</strong>\n");
これらが、実際に出力を行っているところです。このようにして出力されたテキストが、このタグの代りにJSP内に埋め込まれ表示されるわけです。
カスタムタグを使ってみる
では、作成したカスタムタグを実際にJSPから使ってみることにしましょう。ごく単純なJSPファイルにタグを埋め込んでみることにします。
<%@ page language="java" contentType="text/html; charset=windows-31j" pageEncoding="windows-31j"%> <%@ taglib prefix="my" uri="/WEB-INF/mytag.tld" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-31j"> <title>JSP Page</title> </head> <body> ※本日の日付は、<my:MyTag/>です。 </body> </html>
このページにアクセスしてどのように表示されるか確かめてみましょう。今日の日付がボールドで表示されるはずです。このページのソースコードを見て確認してみると、<strong>平成19年7月7日</strong>
というようなテキストが出力されていることがわかるでしょう。
ではJSPのソースを見てみましょう。ここでは、まずタグライブラリとして指定のTLDを使用するように以下のような宣言が書かれているのがわかります。
<%@ taglib prefix="my" uri="/WEB-INF/mytag.tld" %>
これはtaglib
ディレクティブというもので、タグライブラリの情報を記述するためのものです。このタグにはprefix
とuri
という2つの属性が必要になります。uri
は、TLDファイルのある場所を示すものです。prefix
というのは、指定したTLDに定義したタグを使うとき、タグ名の前につけるテキストです。
カスタムタグは、<プレフィクス:タグ名>
という形で記述をします。この場合なら、<my:タグ名>
という形で記述するわけです。上記の場合であれば、my
というプレフィクスのMyTag
というタグを指定していることになり、<my:MyTag/>
と記述されることになります。
属性を追加する
このSimpleTagSupportは、ごくごく単純に1つのタグを書くだけのものです。が、実際に汎用性のあるタグを作ろうと思うとこれではあまり役に立ちそうにありません。それなりに情報を設定してタグに渡す仕組みが欲しくなりますね。
そこで、タグに属性を用意し、この属性を使って渡した値を利用しタグの出力を行わせてみることにしましょう。まずは、TLDファイルの修正からです。<tag>
タグ内に、属性に関するタグを追記します。
<tag> <name>MyTag</name> <tag-class>jp.codezine.MySimpleTag</tag-class> <body-content>empty</body-content> <attribute> <name>color</name> <type>java.lang.String</type> <required>false</required> </attribute> </tag>
新たに追加されたのは、<attribute>
というタグです。これが、タグに用意される属性に関する情報を記すためのものになります。この<attribute>
内には、以下の3つのタグが用意されています。
<attribute> <name>属性名</name> <type>値の種類</type> <required>必須か否か</required> </attribute>
この他にも<attribute>
に用意されるタグはありますが、とりあえずこの3つを覚えておけば十分でしょう。ここでは、「color」という名前の属性を定義しています。これは必須項目ではなく、値はStringとして受け渡されるわけです。
クラスファイルの修正
では、この属性colorを利用して出力するようにMySimpleTagクラスを修正しましょう。なお、package、import文は省略してあります。
public class MySimpleTag extends SimpleTagSupport { private String color = "#000000"; public void doTag() throws JspException, IOException { Locale.setDefault(new Locale("ja","JP","JP")); Calendar cal = Calendar.getInstance(); SimpleDateFormat format = new SimpleDateFormat("GGGGyyyy年M月d日"); JspWriter out = this.getJspContext().getOut(); out.println("<font color=\"" + this.getColor() + "\">"); out.println("<strong>"); out.println(format.format(cal.getTime())); out.println("</strong></font>\n"); } public void setColor(String s){ this.color = s; } public String getColor(){ return this.color; } }
TLDで<attribute>
を使って指定されたタグは、タグ定義のクラス内ではプロパティとして用意されるため、privateフィールドを用意して値を保管し、Setter/Getterによって値をやりとりできるようになっています。例えば、タグにcolor属性が用意された場合には、setColor
が呼び出され値が設定されるわけです。
タグに指定された属性は、そのタグが呼び出されたとき、doTag
の実行の前に値の設定が全て行われます。そうしてSetterによって属性の値がすべて設定された状態になった後にdoTag
が呼び出され、タグの出力が行われます。ただし、<required>
で必須に指定していない場合には、事前に属性設定のためのSetterが呼び出されない場合もあることを忘れないでください。
ここでは、private String color= "#000000";
というようにフィールドに初期値を与えておき、このフィールドの値を<font>
タグのcolor属性の値として書き出しています。これで、color属性で指定した色でテキストが表示されるようになるわけです。
では、修正ができたら、先ほどJSPファイルに記述したタグを少し書き換えてみましょう。例えば、こんな具合にすれば、日付を赤で出力します。
<my:MyTag color="#FF0000"/>