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

来源:互联网 发布:华为手机助手mac版 编辑:程序博客网 时间:2024/05/17 02:19

 

【文章标题】JSP中用自定义标签实现集合的遍历——山寨版<c:foreach>

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ190678908

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

       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/

 

原创粉丝点击