15.JSP2.1 Unified ELのカスタムタグ
Unified ELの遅延評価式「 #{ } 」を使って、値のget,setおよびメソッドの実行ができます。 ここでは、そのためのカスタムタグの作成手順について解説します。 カスタムタグについてはこちらも参照ください。
遅延評価式はその役割によって、変数の値を取り扱うものとメソッドの実行を取り扱うものの2種類を考えることができます。 どちらも「 #{式} 」という形は同じですが、カスタムタグを作成する際に少し違いが出てきます。
3.1. 値のget,set
値のgetおよびsetを行うカスタムタグです。まず、TLD(タグ設定ファイル)で値を取り扱う遅延評価式の受け入れを宣言しておきます。
・・・ <taglib> <tlib-version>1.1</tlib-version> <jsp-version>2.1</jsp-version> <short-name>TestTagLib</short-name> ・・・ <tag> <name>test</name> <tag-class>test.UnifiedELtestTag</tag-class> <body-content>EMPTY</body-content> <attribute> <name>deferred</name> <deferred-value> <type>java.lang.String</type> </deferred-value> </attribute> </tag> </taglib>
name要素は属性の名前であり、ここではdeferredとしました。 deferred-value要素を定義することで値を取り扱う遅延評価式の受け入れを宣言しています。 その子要素のtype要素では評価結果の型を指定します。 ここではString型としました。
次にタグハンドラクラスを作成します。 deferred-value要素で受け入れを宣言した遅延評価式は、ValueExpression型で受け取ることになります。 getValue(ELcontext) で値を評価、setValue(ELcontext, Object) で値をsetします。 getExpressionString() で式全体を取ってくることも可能です。
以下は変数に格納されている値をgetValueメソッドによって評価し、そのまま表示するというタグのハンドラクラスの例です。 またsetValueメソッドの使用法を示す目的で、評価結果の文字列が "TECH" に一致した場合は 末尾に "SCORE" という文字列を連結させて値をsetし直し、表示するようにしています。
package test; import javax.servlet.jsp.tagext.SimpleTagSupport; import javax.servlet.jsp.JspException; import javax.el.ValueExpression; import javax.el.ELContext; import java.io.IOException; public class UnifiedELtestTag extends SimpleTagSupport{ private ValueExpression deferred; public void setDeferred(ValueExpression _deferred) { this.deferred = _deferred; } public void doTag() throws JspException, IOException { String value = ""; ELContext elctx = getJspContext().getELContext(); value = (String) deferred.getValue(elctx); if(value.equals("TECH")){ deferred.setValue(elctx, value + "SCORE"); value = (String) deferred.getValue(elctx); } getJspContext().getOut().print(value); } }
以上のように作成したカスタムタグをJSPページで使ってみます。
<%@ page contentType="text/html; charset=Shift_JIS" import="java.util.ArrayList" isELIgnored="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="t" uri="/WEB-INF/test-tag.tld" %> <jsp:useBean id="list" class="java.util.ArrayList" /> <% list.add("TEC"); list.add("TECK"); list.add("TECH"); %> <html> <body> <c:forEach var="item" items="${list}" > <t:test deferred="#{item}" /><br> </c:forEach> </body> </html>
実行結果は以下のようになります。
TEC TECK TECHSCORE
このように遅延評価を行うことによって、 特定の値に対して処理を追加することが可能です。
3.2 メソッドの実行
次にメソッドの実行を行う遅延評価式のカスタムタグの設定例を説明します。 まず、実行したいメソッドをもつクラスを作成しておきましょう。 ここでは、あらかじめ用意された文字列を返すだけのprintStr()メソッドを用意しておきます。
package test; public class ExampleClass{ public String printStr(){ return "printStr() is invoked."; } }
続いて、値のget,setの場合と同様にTLDでメソッドを実行する遅延評価式の受け入れを宣言しておきます。
・・・ <taglib> <tlib-version>1.1</tlib-version> <jsp-version>2.1</jsp-version> <short-name>TestTagLib</short-name> <tag> <name>test</name> <tag-class>test.UnifiedELtestTag</tag-class> <body-content>EMPTY</body-content> <attribute> <name>method</name> <deferred-method> <method-signature> String printStr() </method-signature> </deferred-method> </attribute> </tag> </taglib>
属性の名前はmethodとしました。 deferred-method要素を定義することでメソッドを実行する遅延評価式の受け入れを宣言しています。 その子要素<method-signature>で、実行させたいメソッドとして先ほど用意したprintStr()を指定します。
JSPでの使用例は以下のようになります。
<%@ page contentType="text/html; charset=Shift_JIS" import="java.util.ArrayList" isELIgnored="false" %> <%@ taglib prefix="t" uri="/WEB-INF/test-tag.tld" %> <jsp:useBean id="example" class="test.ExampleClass" /> <html> <body> <t:test method="#{example.printStr}" /> </body> </html>
実行結果はこうなります。
printStr() is invoked.