forEachカスタムタグでは、繰り返しオブジェクトのデータを、順番に文字型(java.lang.String)の変数の値に、順番に設定します。
itemsは、Array型、Collection型(Vector型)、Iterator型の繰り返しオブジェクトが利用できます。
Enumeration型には対応していませんので、Iterator型を使ってください。
type属性で、設定する変数のクラスを指定することもできます。
複数の項目を繰り返す場合は、クラスを作成し、そのクラス名を指定します。
<ash:forEach var="変数名" type="変数クラス名" items="繰り返し型変数"> <%=変数名%>を使ったJSPの記述 </ash:forEach> |
タグハンドラは、doStartTag、doAfterBodyメソッドを実装します。 タグハンドラの処理では、各種繰り返し型のオブジェクトを、Iterator型に変換しています。 Iterator型の場合は、hasNext()メソッドと、next()メソッドが必要となります。
ForEachTag.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import java.util.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; /** * forEach繰り返し表示タグライブラリ **/ public class ForEachTag extends TagSupport { private String var; private String type; private Object items; private Iterator iterator; /** varの設定 **/ public void setVar(String var) { this.var = var; } /** typeの設定 **/ public void setType(String type) { this.type = type; } /** itemsの設定 **/ public void setItems(Object items) { this.items = items; } /** タグ初期処理(繰り返しの初期処理) **/ public int doStartTag() throws JspException { // データがない場合は処理しない if (items == null) { return SKIP_BODY; } // Array型からIteratorに変換 if (items instanceof Object[]) { Object[] array = (Object[]) items; iterator = Arrays.asList(array).iterator(); // Collection型からIteratorに変換 } else if (items instanceof Collection) { Collection collection = (Collection) items; iterator = collection.iterator(); // Iterator型からIteratorに変換 } else if (items instanceof Iterator) { iterator = (Iterator) items; // その他のデータ型の場合はエラー } else { throw new JspException("Invalid type: " + items.getClass().getName()); } // 次の要素を取得 if (iterator.hasNext()) { pageContext.setAttribute(var, iterator.next()); return EVAL_BODY_INCLUDE; } else { return SKIP_BODY; } } /** 繰り返しの後処理 **/ public int doAfterBody() throws JspException { // データがない場合は処理しない if (iterator == null) { return SKIP_BODY; } // 次の要素を取得 if (iterator.hasNext()) { pageContext.setAttribute(var, iterator.next()); return EVAL_BODY_AGAIN; } else { return SKIP_BODY; } } } |
タグ拡張情報では、設定する変数名(var)を定義します。
ForEachTEI.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import javax.servlet.jsp.tagext.*; /** * forEachタグライブラリの変数定義 **/ public class ForEachTEI extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData tagData) { String varName = tagData.getAttributeString("var"); String varType = tagData.getAttributeString("type"); if (varType == null) { varType = "java.lang.String"; } return new VariableInfo[] { new VariableInfo(varName, varType, true, VariableInfo.NESTED) }; } } |
forEachカスタムタグを使って、Array型のデータと、Vector型のデータの住所録データを表示してみます。
forEachカスタムタグは、Array型にもVector型にも対応しているため、同じようにitemsに繰り返し変数を指定するだけで、addrオブジェクトが順番に設定され、繰り返されます。
Addr.jsp |
---|
<%@ page contentType="text/html; charset=Shift_JIS" %> <%@ taglib prefix="ash" uri="http://ash.jp/taglib_1_0" %> <%@ page import="java.util.*" %> <%! class AddrData { String name; String address; String tel; AddrData (String name, String address, String tel) { this.name = name; this.address = address; this.tel = tel; } } %> <% // Array型住所録データ作成 AddrData[] addrArray = new AddrData[] { new AddrData("升村 丞", "金沢市菊川", "076-261-4921"), new AddrData("北陸 太郎", "金沢市大手町", "076-221-1429"), new AddrData("金沢 花子", "金沢市片町", "090-2377-2056") }; // Vector型住所録データ作成 Vector addrVector = new Vector(); addrVector.add(new AddrData("升村 丞", "金沢市菊川", "076-261-4921")); addrVector.add(new AddrData("北陸 太郎", "金沢市大手町", "076-221-1429")); addrVector.add(new AddrData("金沢 花子", "金沢市片町", "090-2377-2056")); %> <html> <head><title>住所録</title></head> <body> <h1>住所録</h1> <h2>Array型</h2> <table border="2"> <ash:forEach var="addr" type="AddrData" items="<%= addrArray %>"> <tr> <td><%= addr.name %></td> <td><%= addr.address %></td> <td><%= addr.tel %></td> </tr> </ash:forEach> </table> <h2>Vector型</h2> <table border="2"> <ash:forEach var="addr" type="AddrData" items="<%= addrVector %>"> <tr> <td><%= addr.name %></td> <td><%= addr.address %></td> <td><%= addr.tel %></td> </tr> </ash:forEach> </table> </body> </html> |
JSPで、Array型やCollection型(Vector型)やIterator型の、繰り返しデータの内容を表示します。 以下に、この画面を表示するためのサンプルソースを示しています。
ForEach.jspは、ForEachサーブレットから呼び出されます。
JSPのソースでは、Array型、Collection(Vector)型、Iterator型の繰り返し変数の内容を表示しています。
ForEach.jsp |
---|
<%@ page contentType="text/html; charset=Shift_JIS" %> <%@ taglib prefix="ash" uri="http://ash.jp/taglib_1_0" %> <jsp:useBean id="foreach" class="jp.ash.taglib.ForEachData" scope="request" /> <html> <head><title>forEachタグのテスト</title></head> <body> <h1>forEachタグのテスト</h1> <h2>Array</h2> <table border="2"><tr> <ash:forEach var="var" items="<%= foreach.array %>"> <td><%= var %></td> </ash:forEach> </tr></table> <h2>Collection(Vector)</h2> <table border="2"><tr> <ash:forEach var="var" items="<%= foreach.collection %>"> <td><%= var %></td> </ash:forEach> </tr></table> <h2>Iterator</h2> <table border="2"><tr> <ash:forEach var="var" items="<%= foreach.iterator %>"> <td><%= var %></td> </ash:forEach> </tr></table> </body> </html> |
データクラスでは、各種繰り返しデータの設定を行います。
ForEachData.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import java.util.*; /** forEach繰り返しデータ **/ public class ForEachData { /** Array型データ **/ public String[] array; /** Collection型データ **/ public Vector collection; /** Iterator型データ **/ public Iterator iterator; ForEachData() { // Array型データの作成 array = new String[] {"data01", "data02", "data03"}; // Collection型への変換 collection = new Vector(); for (int i = 0; i < array.length; i++) { collection.add(array[i]); } // Iterator型への変換 iterator = collection.iterator(); } } |
forEachカスタムタグテストの制御用のサーブレットを作成します。
ForEachServlet.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** forEach繰り返し表示サーブレット **/ public class ForEachServlet extends HttpServlet { public void service (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // ForEachオブジェクトの作成 foreach = new ForEachData(); req.setAttribute("foreach", foreach); // 画面の表示 req.getRequestDispatcher("ForEach/ForEach.jsp").forward(req, res); } } |
forカスタムタグは、回数を指定して、繰り返し処理を行います。
変数の値を開始値から終了値を越えるまで、増分値だけ増加させながら処理します。
増分値に負の数は指定できません。
配列を繰り返す場合は、配列サイズを指定することもできます。
<ash:for var="変数名" begin="開始値" end="終了値" step="増分値" length="配列サイズ"> <%=変数名%>を使ったJSPの記述 </ash:for> |
タグハンドラは、doStartTag、doAfterBodyメソッドを実装します。
ForTag.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import java.util.*; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; /** * for繰り返し表示タグライブラリ **/ public class ForTag extends TagSupport { /** カウンタ変数名 **/ private String var; /** カウンタクラス名 **/ private int begin = 0; /** カウンタ終了値 **/ private int end = -1; /** カウンタ増分値 **/ private int step = 1; /** カウンタ値 **/ private int count; /** varの設定 **/ public void setVar(String var) { this.var = var; } /** beginの設定 **/ public void setBegin(int begin) { this.begin = begin; } /** endの設定 **/ public void setEnd(int end) { this.end = end; } /** stepの設定 **/ public void setStep(int step) { this.step = step; } /** lengthの設定 **/ public void setLength(int length) { this.end = length - 1; } /** タグ初期処理 **/ public int doStartTag() throws JspException { // データがない場合は処理しない if (var == null) { return SKIP_BODY; } // カウンタの設定 count = begin; pageContext.setAttribute(var, new Integer(count)); // 終了判定 if (end < count) { return SKIP_BODY; } else { return EVAL_BODY_INCLUDE; } } /** BODYタグ後処理 **/ public int doAfterBody() throws JspException { // データがない場合は処理しない if (var == null) { return SKIP_BODY; } // カウンタの設定 count = count + step; pageContext.setAttribute(var, new Integer(count)); // 終了判定 if (end < count) { return SKIP_BODY; } else { return EVAL_BODY_AGAIN; } } } |
タグ拡張情報では、設定する変数名(var)を定義します。
ForTEI.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import javax.servlet.jsp.tagext.*; /** * forタグライブラリの変数定義 **/ public class ForTEI extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData tagData) { String varName = tagData.getAttributeString("var"); String varType = "java.lang.Integer"; return new VariableInfo[] { new VariableInfo(varName, varType, true, VariableInfo.NESTED) }; } } |
JSPで、繰り返し型のインデックスで、配列の内容を表示します。 以下に、この画面を表示するためのサンプルソースを示しています。
JSPでforカスタムタグを利用したサンプルです。
For.jsp |
---|
<%@ page contentType="text/html; charset=Shift_JIS" %> <%@ taglib prefix="ash" uri="http://ash.jp/taglib_1_0" %> <jsp:useBean id="fordata" class="jp.ash.taglib.ForData" scope="request" /> <html> <head><title>forタグのテスト</title></head> <body> <h1>forタグのテスト</h1> <h2>Array(begin、end指定)</h2> <table border="2"> <ash:for var="idx" begin="1" end="3"> <tr> <td><%= idx %></td> <td><%= fordata.array[idx.intValue()] %></td> </tr> </ash:for> </table> <h2>Array(step指定)</h2> <table border="2"> <ash:for var="idx" begin="0" end="4" step="2"> <tr> <td><%= idx %></td> <td><%= fordata.array[idx.intValue()] %></td> </tr> </ash:for> </table> <h2>Array(length指定)</h2> <table border="2"> <ash:for var="idx" length="<%= fordata.array.length %>"> <tr> <td><%= idx %></td> <td><%= fordata.array[idx.intValue()] %></td> </tr> </ash:for> </table> </body> </html> |
forカスタムタグテスト用データクラスでは、各種繰り返しデータの設定を行います。
ForData.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import java.util.*; /** for繰り返しデータ **/ public class ForData { /** Array型データ **/ public String[] array; ForData() { // Array型データの作成 array = new String[] { "data00", "data01", "data02", "data03", "data04" }; } } |
forカスタムタグテストの制御用のサーブレットを作成します。
ForServlet.java |
---|
// Copyright (C)1995-2002 ASH multimedia lab. http://ash.jp/ package jp.ash.taglib; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** for繰り返し表示サーブレット **/ public class ForServlet extends HttpServlet { public void service (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Forオブジェクトの作成 fordata = new ForData(); req.setAttribute("fordata", fordata); // 画面の表示 req.getRequestDispatcher("For/For.jsp").forward(req, res); } } |
タグライブラリの情報をタグライブラリ記述子に設定します。
taglib.tld |
---|
<?xml version="1.0" encoding="Shift_JIS" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>ash</short-name> <uri>http://ash.jp/taglib_1_0</uri> <description>ASHのタグライブラリ</description> <tag> <name>forEach</name> <tag-class>jp.ash.taglib.ForEachTag</tag-class> <tei-class>jp.ash.taglib.ForEachTEI</tei-class> <body-content>JSP</body-content> <description>forEach繰り返しタグライブラリ</description> <attribute> <name>var</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>type</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <type>java.lang.Object</type> </attribute> </tag> <tag> <name>for</name> <tag-class>jp.ash.taglib.ForTag</tag-class> <tei-class>jp.ash.taglib.ForTEI</tei-class> <body-content>JSP</body-content> <description>for繰り返しタグライブラリ</description> <attribute> <name>var</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>begin</name> <required>false</required> <rtexprvalue>true</rtexprvalue> <type>int</type> </attribute> <attribute> <name>end</name> <required>false</required> <rtexprvalue>true</rtexprvalue> <type>int</type> </attribute> <attribute> <name>step</name> <required>false</required> <rtexprvalue>true</rtexprvalue> <type>int</type> </attribute> <attribute> <name>length</name> <required>false</required> <rtexprvalue>true</rtexprvalue> <type>int</type> </attribute> </tag> </taglib> |
タグライブラリ記述子をデプロイメント記述子に設定します。
web.xml |
---|
<?xml version="1.0" ?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <taglib> <taglib-uri>http://ash.jp/taglib_1_0</taglib-uri> <taglib-location>/WEB-INF/taglib.tld</taglib-location> </taglib> </web-app> |