您的位置:首页 > Web前端 > JavaScript

在JSP中用自定义标签实现集合的遍历——山寨版c:foreach

2011-09-17 17:33 585 查看
【文章标题】在JSP中用自定义标签实现集合的遍历——山寨版<c:foreach>
【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ】190678908

*******************************************************************************

在JSTL中,标签<c:foreach></c:foreach>可方便地遍历集合或数组,在了解了自定义标签后,可动手实现<c:foreach>标签的功能。

在编写自定义标签前,总要把实验环境搭建好^-^

首先,定义一个Person类,在实验的集合中就是存放这个类的实例,代码如下:

package com.javaeye.newjueqi;

/**
* 实验类Person
*/
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

}

既然是遍历集合,那么集合也是必须的,我们在测试页面TestMyELTag.jsp上写下如下的JSP代码,生成一个测试用途的集合ArrayList,集合中有三个元素

<%
//第1个人对象
Person p1=new Person();
p1.setName("Tom");
p1.setAge(23);

//第2个人对象
Person p2=new Person();
p2.setName("Mike");
p2.setAge(33);

//第3个人对象
Person p3=new Person();
p3.setName("Jack");
p3.setAge(43);

ArrayList list=new ArrayList();
list.add( p1 );
list.add( p2 );
list.add( p3 );

//把ArrayList存储在application
pageContext.setAttribute( "PersonList", list );

%>

在编写 “山寨版”<c:foreach>前,有必要先了解一下正版的<c:foreach>的标准用法是怎么样的。如果用<c:foreach>遍历上述的集合写法如下:

<c:forEach items="${pageScope.personlist}" var="per" >

${per.name } -- ${per.age } <br>
</c:forEach>

<c:foreach>是循环控制,可以将集合中的成员循序遍历一遍,运行方式为条件符合时,将会重复执行<c:foreach>的本体内容。

<c:foreach>中的属性的含义:items是被迭代的集合对象,var是用来存放现在指向的成员,上面的代码运行后的结果如图1所示:

图1

我们实现一个自定义的标签<newjueqi: myforEach>,模拟实现<c:forEach>的功能,用法如下:

<!-- 使用自定义标签模拟实现<c:forEach>中集合的遍历功能 -->
<newjueqi:myforEach items="${pageScope.personlist}" var="per">
${per.name } -- ${per.age } <br>
</newjueqi:myforEach>

效果如图1 所示

下面是正式的代码:

1. 编写一个自定义的标签类。

/**
* 完成模拟<c:forEach>标签遍历集合的功能
*/
public void doTag() throws JspException, IOException {
// 定义一个迭代器
Iterator i=null;

//如果集合是Colleciton类型
if( items instanceof Collection )
{
//获取Collection的迭代器
i=( (Collection)items).iterator();
}
//如果集合是数组类型
else if( items instanceof Object[] )
{
//用Arrays的静态方法asList把数组转换为一个List集合,由于asList接受的参数
//是可变参数,所以为了防止转换出错必须要把传入 的参数强制为数组
i=Arrays.asList((Object[])items).iterator();
}
else
{
throw new RuntimeException("不能转换");
}

//进行迭代
while( i.hasNext() )
{
//取得集合中迭代器指向的对象
Object obj=i.next();

//用setAttribute方法把对象和指定 的变量连接起来
//例如标签中有属性var="per",标签体中有EL表达式式:$(per.name)
//写了下面的一句话后EL表达式就可理解为obj.getName(),表示调用的是
//对象相应的getXXX()
pageContext.setAttribute( var, obj );

//执行标签体的内容
jspFragment.invoke( null );
}
}

2. 根据自定义标签的写法,首先写一个tld文件配置自定义标签。由于标签<newjueqi: myforEach>是带有属性和标签体的,所以编写如下:

<!-- 配置一个自定义标签 -->
<tag>
<!-- 指定自定义标签的名字 -->
<name>myforEach</name>
<!-- 指定当前标签关联的 Java 类 -->
<tag-class>com.javaeye.newjueqi.MyForEach</tag-class>
<!-- 指定标签体的类型: -->
<body-content>scriptless</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

3. 在JSP页面中导入标签。

<%@ taglib prefix="newjueqi" uri="http://newjueqi.javaeye.com/myforEach" %>

4. 在JSP页面中使用自定义标签测试实际的效果。

<!-- 使用自定义标签模拟实现<c:forEach>中集合的遍历功能 -->
<newjueqi:myforEach items="${pageScope.personlist}" var="per">
${per.name } -- ${per.age } <br>
</newjueqi:myforEach>

运行的实际效果如图 1所示

结语:这个自定义标签遍历集合的功能还不完善,譬如不能遍历Map集合中的元素,但它们的编写思路是一致的, Map集合中需要进一步封装对象。

文章附件下载:http://newjueqi.ys168.com/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: