Section12 カスタムタグライブラリのデザインと開発

このページまとまりがない。。。

12.1 下記のカスタムタグライブラリディスクリプタの要素名を確認する。

以下がTLDとルート要素taglibの例です。

<?xml version="1.0" encoding="Shift?_JIS" ?>
<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>c</short-name>

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

</taglib>
taglib要素のDTD
<!ELEMENT taglib (tlib-version, jsp-version, short-name, uri?,
                  display-name?, small-icon?, large-icon?, description?,
                  validator?, listener*, tag+) >

tag要素の例です。

<tag>
  <name>echo</name>
  <tag-class>tag01.EchoTag</tag-class>
  <body-content>EMPTY</body-content>
  <attribute>
    <name>message</name>
    <required>false</required>
  </attribute>
</tag>

tag要素のDTD
nameとtag-classは必須で、後は任意です。

<!ELEMENT tag (name, tag-class, tei-class?, body-content?, display-name?,
               small-icon?, large-icon?, description?, variable*, attribute*,
               example?) >

tag要素の子要素の説明
タグ名 説明
name ユニークなタグの名前
tag-class javax.servlet.jsp.tagext.Tagを実装した
タグハンドラのクラス名。

tei-class

An optional subclass of
javax.servlet.jsp.tagext.TagExtraInfo

body-content ボディ内容のタイプ
指定する内容は以下のうち1つ
tagdependent
JSP
empty

display-name

ツールで利用される短い表示名

small-icon

ツールで利用されるアイコン(小)

large-icon

ツールで利用されるアイコン(大)

description

タグの説明文

variable

Optional scripting variable information

attribute タグの属性

example

Optional informal description of an example of a
use of this tag

12.2 下記を宣言するカスタムタグを説明する。

attribute要素のDTDはコレ。

<!ELEMENT attribute (name, required? , rtexprvalue?, type?, description?) >

attribute要素の子要素の説明
要素名 必須 説明
name 必須 タグ属性名
required 任意 この属性が必須かどうか
true、false、yes、noのどれか1つを指定
省略した場合はfalse
rtexprvalue 任意 この属性がスクリプトレットで動的に計算されるかどうか
<hoge:echo message="1" />とJSPに値を書く場合はfalseを指定。
true、false、yes、noのどれか1つを指定
省略した場合はfalse
例えば、
<hoge:echo message="<%=request.getParameter("hoge")>"などのように
実行時に値が決まる場合はtrueを指定します。

type

任意

この属性の型を指定します。
普通は、省略し、java.lang.String型で値を渡します。

description

任意

この属性の説明

12.3 与えられたカスタムタグで、以下のタグタイプの中でTLDファイル内 bodycontentの必要値を説明する

bodycontentに指定する値は以下のどれかです。
説明
JSP 他のJSPコードを囲むタグで指定します。
empty 本体のないタグで指定します。
tagdependent

タグハンドルにのみ使用されるコンテンツを囲むタグ?

省略した場合のデフォルトはJSPです。

emptyを指定した場合、JSP側

<t:mytag>aaa</t:mytag>
のようにタグに囲まれた要素を書くとJSPコンパイル時のエラーとなる。 (ただし要素が半角や全角の空白の場合、うちの Tomcatではエラーだが仕様上はOKなのか?不明)

12.4 下記のタグタイプのメソッドを呼び出し、トリガーとなる正しい記述

メソッド 説明
doStartTag 開始タグの処理時に呼ばれます。
doAfterBody IterationTagインターフェイスを実装したタグクラスで、
タグのボディ部が評価された後に呼ばれます。
doEndTag 終了タグの処理時に呼ばれます。

12.5 下記メソッドの有効な戻り値を記述

メソッド 有効な値 説明
doStartTag EVAL_BODY_INCLUDE タグのボディを評価する
EVAL_BODY_BUFFERED 新しいBodyContextバッファを作成し、
その中でボディの評価を行する。
SKIP_BODY タグのボディを評価しない
doAfterBody EVAL_BODY_AGAIN 再びボディを評価する。
SKIP_BODY 再びボディを評価しない。
doEndTag EVAL_PAGE 残りのJSPページを評価する
SKIP_PAGE 残りのJSPページを評価しない
PageContext.getOut JspWriter 暗黙オブジェクトoutに同じ

タグの返り値によるフローを図にするとたぶんこんな感じ。

12.6 BODY,PAGE定数を与えられ、下記のメソッドでの定数の正しい使用法を記述

上の表参照

12.7 下記にアクセスするカスタムタグハンドラのメソッドを記述

PageContextのメソッドを使います。

JSPページの暗黙オブジェクト

pageContext.getOut()
pageContext.getRequest()
etc...

JSPページの属性

pageContext.findAttribute(String name)
pageContext.getAttribute(String name)
pageContext.getAttribute(String name, int scope)
pageContext.getAttributeNamesInScope(int scope)

12.8 インナータグハンドラの中からアウタータグハンドラに戻るメソッドを記述

javax.servlet.jsp.tagext.TagSupport#findAncestorWithClass(Tag from, Class klass)
引数のklass型で、このタグを囲んでいるTagの中の最も近い親Tagを探します。
内部的にgetParent()を使います。

javax.servlet.jsp.tagext.Tag#getParent()
このタグを囲んでいる親Tagを返します。

補足

カスタムタグを作るには以下のインターフェイス、クラスのどれかを 実装、継承します。
Interface/class 説明
Tag すべてのカスタムタグの共通インターフェイス
IterationTag ボディ部を(繰り返し)評価するインターフェイス
TagSupport IterationTagの標準実装クラス
BodyTag IterationTagを拡張したインターフェイス。
doStartTag()がEVAL_BODY_BUFFEREDを返したときに、 doAfterBody()が呼ばれます。
BodyTagSupport BodyTagの標準実装クラス

継承関係をクラス図で書くと以下のようになります (主要なメソッドのみ表記)。

UML by Poseidon UML