Section11 カスタムタグを使用したJSPのデザインと開発

11.1 Webアプリケーションweb.xmlで適切にフォーマットされたタグライブラリ宣言を説明する。

web.xmlの<taglib>タグでカスタムタグを宣言します。

<taglib>
  <taglib-uri>http://muimi.com/tag01</taglib-uri>
  <taglib-location>/WEB-INF/tag01.tld</taglib-location>
</taglib>

taglib要素のDTD

<!ELEMENT taglib (taglib-uri, taglib-location)>

<taglib-uri>にはJSPで指定するタグライブラリの名前を指定します。 実在するURLでなくてもかまいませんが、 他のタグライブラリと同じ名前にならない、 ユニークな名前である方が望ましいです(URLならユニーク)。

<taglib-location> タグライブラリディスクリプタの場所を指定します。 Webアプリケーションのルートからの相対パスです。

11.2 JSPページで適切にフォーマットされたタグライブラリディレクティブを説明する

JSPページでは、taglibディレクティブでTLDファイル(タグライブラリディスクリプタ) の場所を指定します。

<%@ taglib uri="http://muimi.com/tag01&lt;/taglib-uri" prefix="t" %>
なお、web.xmlにtag-libの記述をせずに、TLDファイルの場所を直接指定することも可能です。
<%@ taglib uri="tag01.tld" prefix="t" %>
後々の修正を考えると、web.xmlに記述した方がよいですが、 簡単にタグライブラリのテストをしたい場合は、相対パスなどで直接TLD指定でもいいでしょう。

11.3 与えられたカスタムタグライブラリで、下記を使用したJSPページにおける適切にフォーマットされたカスタムタグの使用法を説明する

作ってみないと、何がなんだか分からなかったので、いくつか 簡単なものをいくつか作ってみました。
目的 サンプル名 説明
本体のないカスタムタグ HelloTag helloと表示する。
属性のあるカスタムタグ EchoTag 属性messageに指定された値を表示する。
カスタムタグ囲んだ中身を評価するタグ TagTag タグボディの値を、属性tagに指定されたHTMLタグで囲って出力する。
JSP記述<t:tag="b">hoge</t:tag>→出力<b>hoge</b>
ネストされたカスタムタグ ChildTag 親タグインスタンスの属性を取得し、出力します。

HelloTag

タグクラス

package tag01;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class HelloTag extends TagSupport{

  public int doStartTag() throws JspException {
    try{
      pageContext.getOut().println("hello");
      return SKIP_BODY;
    }catch(IOException e){
      throw new JspException(e);
    }
  }
}

TLD

  <tag>
    <name>hello</name>
    <tag-class>tag01.HelloTag</tag-class>
    <body-content>EMPTY</body-content>
  </tag>

JSP

<t:hello />

実行結果

hello

EchoTag

タグクラス

package tag01;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class EchoTag extends TagSupport{

  private String message = "no message";

  public int doStartTag() throws JspException{

    try{
      JspWriter out = pageContext.getOut();
      out.println(message);
      return SKIP_BODY;

    }catch(IOException e){
      throw new JspException(e);
    }
  }

  public void setMessage(String message) {
    this.message = message;
  }
}
TLD
  <tag>
    <name>echo</name>
    <tag-class>tag01.EchoTag</tag-class>
    <body-content>EMPTY</body-content>
    <attribute>
      <name>message</name>
      <required>false</required>
    </attribute>
  </tag>
JSP
<t:echo message="hey you!" />

実行結果

hey you!

TagTag

ソース

package tag01;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class TagTag extends TagSupport{

  private String tag;

  public int doStartTag() throws JspException{

    try{
      JspWriter out = pageContext.getOut();
      out.print("<" + tag + ">");
      return EVAL_BODY_INCLUDE;

    }catch(IOException e){
      throw new JspException(e);
    }
  }

  public int doEndTag() throws JspException {
    try{
      JspWriter out = pageContext.getOut();
      out.print("</" + tag + ">");
      return EVAL_PAGE;

    }catch(IOException e){
      throw new JspException(e);
    }
  }

  public void setTag(String tag) {
    this.tag = tag;
  }
}

TLD

  <tag>
    <name>tag</name>
    <tag-class>tag01.TagTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
      <name>tag</name>
      <required>true</required>
    </attribute>
  </tag>

JSP

<t:tag tag="i">
It is Italic
</t:tag>

実行結果

<i>
It is Italic
</i>

ChildTag

タグクラス

package tag01;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class ChildTag extends TagSupport{

  private String name;

  public int doStartTag() throws JspException {

    ChildTag parent = (ChildTag)findAncestorWithClass(this, ChildTag.class);

    if(parent == null){
      try{
        pageContext.getOut().print("私は" + name + "です。");
      }catch(IOException e){
        throw new JspException(e);
      }
    }else{
      String parentName = parent.getName();
      try{
        pageContext.getOut().print("私は" +parentName+ "の子供の" + name + "です。");
      }catch(IOException e){
        throw new JspException(e);
      }
    }
    return EVAL_BODY_INCLUDE;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

TLD

  <tag>
    <name>child</name>
    <tag-class>tag01.ChildTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
      <name>name</name>
      <required>true</required>
    </attribute>
  </tag>

JSP

<t:child name="太郎"><br>
  <t:child name="次郎"><br>
    <t:child name="三郎"><br>
    </t:child>
  </t:child>
</t:child>

実行結果

私は太郎です。
私は太郎の子供の次郎です。
私は次郎の子供の三郎です。