カスタムタグはJakartaTaglibsしか存在していないというわけではなく、自作することができます。
カスタムタグの部分はJavaの作成者たちが特に力を入れた部分であり、まさに正気の沙汰ではない実装になっています。
タグの作り方は何通りもあるのですが、とりあえず一番簡単な方法から行ってみます。
まずWEB-INF/tagsディレクトリを作成し、hello.tagという名前のテキストファイルを作成します。
これがタグの処理内容を示すファイルになります。
/WEB-INF/tags/tag1.tag
<%@ tag pageEncoding="Shift_JIS" %> <p>Hello World</p> |
本当にただHelloWorldを出力しているだけです。
<%@ tag pageEncoding>には文字コードを指定します。
タグファイルは<filter>の範囲外なので、例によって毎回書かなければなりません。
JSPファイルでは、以下のような書き方で作成したタグを呼び出すことができます。
tag1.jsp
<%@taglib tagdir='/WEB-INF/tags' prefix='tag' %> <tag:tag1 /> |
tagdirで設定したディレクトリの中にある.tagファイルが、ファイル名で自動的にタグとして使えるようになります。
実に簡単ですね。
属性の受け渡しは以下のようになります。
tag2.jsp
<tag:tag2 data="aaaaa"/> |
/WEB-INF/tags/tag2.tag
<%@ tag pageEncoding="Shift_JIS" %> <%@ attribute name="data" type="java.lang.String" required="true" rtexprvalue="true"%> |
${data}が渡されました。
JSP側では普通のHTMLタグのように名前と属性を指定するだけです。
タグファイル側では、<%@ attribute%>で属性の書式を設定します。
設定値は、nameが受け取る属性名、typeが属性の型(デフォルトはString)、requiredが必須かどうか(デフォルトはfalse)、rtexprvalueは属性値としてELを受け付けるかどうか(デフォルトはtrue)です。
デフォルトでは属性を書いても書かなくてもかまいませんが、required="true"を設定すると必ずその属性を記述しなければなりません。
デフォルトでは<tag:tag2 data="${ELdata}"/>といった書き方が可能ですが、rtexprvalue="false"が指定されているとエラーになります。
さて、以上のタグはタグボディを完全に無視していました。
<tag:tag1>ここがタグボディ</tag:tag1>と書いても、無かったことにされてしまうのです。
次はタグボディを評価してみます。
tag3.jsp
<tag:tag3>${data}</tag:tag3> 帰ってきた値:${tag3request} |
/WEB-INF/tags/tag3.tag
<%@ tag pageEncoding="Shift_JIS" %> <%@ tag body-content='scriptless' %> 渡された値:<jsp:doBody /> <jsp:doBody var="tag3request" scope="request" /> スコープに入れた値:${requestScope.tag3request}<br> |
独特な書式ですが、<jsp:doBody>でタグボディを取得することができます。
属性を何も記述しない場合、そのままその部分に文字列で出力します。
varを指定すると指定された変数に格納されます。
タグボディを加工したい場合などに利用します。
<%@ tag body-content%>の部分で、タグボディの評価方法を指定します。
上記のようにscriptlessを指定するとELを使用できます。
dataに入っている値が表示されます。
tagdependentを指定すると、タグボディが文字列として評価されます。
${data}という文字列のまま出力されます。
emptyと指定した場合、タグボディを記述することができません。
<br />等のボディなしで完結するタグ用ですが、タグボディを記述してしまうとエラーになるので不便です。
何れにせよ、指定にかかわらずスクリプトレットは常時使用できません。
tagdependentの場合は単に文字列になりますが、scriptlessの場合タグボディ内にスクリプトを書くとエラーになります。
このように、いくつか制限はありますがJSPでカスタムタグを作るのはわりと簡単です。
では次に、Javaサーブレットで/WEB-INF/tags/tag1.tagと同じものを作ってみましょう。
/helloTag.jsp
<%@ taglib uri="http://localhost:8080/example/tags/helloTag" prefix="hw" %> <hw:helloTag /> |
src/tag/helloTag.java
package tag; |
/WEB-INF/web.xml
<jsp-config> <taglib> <taglib-uri>http://localhost:8080/example/tags/helloTag</taglib-uri> <taglib-location>/WEB-INF/lib/hello.tld</taglib-location> </taglib> </jsp-config> |
/WEB-INF/lib/hello.tld
<?xml version="1.0" ?> <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> <jsp-version>2.0</jsp-version> <short-name>hw</short-name> <tag> <name>helloTag</name> <tag-class>tag.helloTag</tag-class> <body-content>empty</body-content> </tag> </taglib> |
これ考えたやつは何なの?馬鹿なの?死ぬの?