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>
|