13. フラグメント
2006.06.30 株式会社四次元データ 宮澤了祐
- 13.1. フラグメント
- 13.2. 属性値へのフラグメントの使用
13.1. フラグメント
JSP2.0より「フラグメント」という概念が取り込まれました。 フラグメントとはその名の通りJSPソースの断片を意味します。 具体的にはjavax.servlet.jsp.tagext.JspFragmentのインスタンスです。
特徴として、JspFragmentのinvoke()メソッドを呼び出した際にJspコードの評価を行うという特徴があります。 ただし
SimpleTagのボディ部は、実行時にJspFragmentオブジェクトとして取得されますが、「body-content」属性によって動作が違います。
「body-content」属性がscriptlessであれば、ボディ部のJSPコードを実行します。 「body-content」の属性にtagdependentを指定していた場合、 ボディ部が有効なJSPコードを含んでいたとしても解釈されることはありません。 invoke()メソッドが呼ばれた際にテキストそのままの形で出力されます。
また、SimpleTagのボディ部にスクリプトレットを記述することは出来ません。
例えばボディ部に以下の様なコードが記述されていた場合、
<myTag:hoge>
${1+2}
</myTag:hoge>
「scriptless」を指定していれば「3」と、「tagdependent」を指定していれば「${1+2}」とテキストそのままの形で出力されます。
invoke()メソッドが呼ばれた際に、初めてJSPコードとして解釈されることを解説するために、 次のようなカスタムタグを作成します。
まず message というプロパティを持つBeanを作成します。
SampleBean.java
public class SampleBean{
String message;
public void setMessage(String str){
message = str;
}
public String getMessage(){
return message;
}
}
次にFragmentTestを呼びだすJSPを作成します。
sample.jsp
<%@ page contentType="text/html; charset=euc-jp" import="SampleBean" %>
<%@ taglib uri="http://www.TechScore.com/FragmentTest" prefix="myTag" %>
<%
SampleBean obj = new SampleBean();
obj.setMessage("スクリプトで設定");
request.setAttribute("result", obj);
%>
<jsp:useBean id="result" class="SampleBean"/>
<p>
<jsp:getProperty name="result" property="message" />
</p>
<myTag:FragmentTest>
<jsp:getProperty name="result" property="message" />
</myTag:FragmentTest>
<jsp:getProperty>はBeanの指定したプロパティを出力するアクションタグです。
次のようにタグを定義します。
<tag> <name>FragmentTest</name> <tag-class>FragmentTest</tag-class> <body-content>scriptless</body-content> </tag>
続いてFragmentTestのタグクラスを作成します。中心部分以外を省略します。
public class FragmentTest implements SimpleTag {
...
private JspFragment body;
public void setJspBody(JspFragment body) {
this.body = body;
}
public void doTag() throws JspException, IOException {
SampleBean bean = new SampleBean();
bean.setMessage("ボディ部で設定");
context.setAttribute("result",bean);
body.invoke(context.getOut());
}
...
}
これは次のように出力されます。
スクリプトで設定 ボディ部で設定
まず最初の<jsp:getProperty>で、スコープに登録されているオブジェクトのmessageプロパティが出力されます。 resultという名前のオブジェクトのmessageプロパティには「スクリプトで設定」という文字列が保存されています。
次にFragmentTestのdoTag()メソッドが呼びだされます。
message.invoke()が呼ばれた時点で、初めてボディ部の<jsp:getProperty/>が解釈され、 次のようなjavaコードに変換され、実行されます。 (簡易的に表記しただけなので、実際のコードとは違います。)
out.write(((SampleBean)context.findAttribute("result")).getMessage());
ここで初めてスコープに登録されているオブジェクトを調べるので、 新たに登録された「ボディ部で設定」という文字列をmessageプロパティに持つ、 SampleBeanオブジェクトが参照され、出力されます。
13.2. 属性値へのフラグメントの使用
JSP2.0より新たに属性を指定するアクションタグが追加されました
<jsp:attribute name="属性名"> ここにJSPコードを記述します。 ただしスクリプトレットは使用出来ません。 </jsp:attribute>
<Jsp:attribute>タグはnameで記述した属性に、Body部で設定した値を送るアクションタグです。 これを使用することで、属性値をフラグメントとしてカスタムタグに送ることが出来ます。
フラグメントとして受け取るためには、タグ定義ファイルの<attribute>の<fragment>をtrueに設定されます。 属性の型は自動的にjavax.servlet.jsp.tagext.JspFragmentになり、ほかの値を指定しても無視されます。
<tag>
<name>MySimpleTag4</name>
<tag-class>sample.MySimpleTag4</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>message</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
</tag>
<myTag:MySimpleTag4> <jsp:attribute name="message"> 属性値がフラグメントとして渡されています。 </jsp:attribute> </myTag:MySimpleTag4>
続いてカスタムタグクラスです。SimpleTagを用いて作成しましたが、他のTagインターフェイスを用いても同様にJspFragmentで受け取ることが出来ます。
public class MySimpleTag4 implements SimpleTag {
...
private JspFragment message;
public void setMessage(JspFragment str){
this.message = str;
}
public void doTag() throws JspException, IOException {
message.invoke(context.getOut());
}
...
}
JspFragment型の属性messageを受け取るsetMessage()メソッドにより属性を受け取っています。 JspFragmentのinvoke()メソッドを実行することで属性値が実行され、次のように出力されます。
属性値がフラグメントとして渡されています。

