【自定义标签开发】09-标签案例-开发foreach标签

我们接下来开发一个迭代集合的标签。我们知道struts中有一个<s:iterator>标签用来迭代集合,我们接下来模仿它写一个自定义标签。

前台的效果如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/example" prefix="z" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Hello</title>
  </head>
 
  <body>
      
      <%
           List<String> list=new ArrayList<String>();
           list.add("张三");
           list.add("李四");
           list.add("王五");
           request.setAttribute("nameList",list);
       %>
      
       <z:foreach var="str" items="${nameList}">
           姓名:${str}<br/>
       </z:foreach>
  </body>
 
</html>

首先创建标签处理器类:


然后编写其中的逻辑:
package org.zyg.web.exampleTag;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class ForeachTag extends SimpleTagSupport {
    //传入数组、Map、List都有可能,所以用Object来接收参数
    private Object items;
    private String var;
    
    public void setItems(Object items) {
        this.items = items;
    }
    public void setVar(String var) {
        this.var = var;
    }

    @Override
    public void doTag() throws JspException, IOException {
        //对集合进行迭代
        List list=(List)items;
        Iterator it=list.iterator();
        while(it.hasNext()){
            Object value=it.next();
            //将迭代的值放入PageContext中的var值下
            this.getJspContext().setAttribute(var, value);
            //将标签体显示在页面上
            this.getJspBody().invoke(null);
        }
    }
}

然后在z.tld配置文件中注册该标签:
<tag>
    <name>foreach</name><!-- 标签名 -->
    <tag-class>org.zyg.web.exampleTag.ForeachTag</tag-class>
    <body-content>scriptless</body-content><!-- 有无标签体(单标签还是成对标签) -->

    <attribute>
        <name>var</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    
    <attribute>
        <name>items</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>

重启Web应用测试:


发现我们已经成功的将List集合迭代出来。

现在我们的迭代标签只能迭代List集合,我们还不能迭代Map和数组等其他类型的集合数据,我们下面进行改进。

我们的预期前段效果为:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/example" prefix="z" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Hello</title>
  </head>
 
  <body>
      
      <%
          List<String> list=new ArrayList<String>();
          list.add("张三");
          list.add("李四");
          list.add("王五");
          request.setAttribute("nameList",list);
       %>
       <z:foreach var="str" items="${nameList}">
           姓名:${str}<br/>
       </z:foreach>
      
       <%
          Map<String,String> map=new HashMap<String,String>();
          map.put("总部","上海");
          map.put("分销处","广州");
          map.put("人力资源部","深圳");
          map.put("销售部","北京");
          request.setAttribute("localmap",map);
       %>
       <z:foreach var="entry" items="${localmap}">
           ${entry.key}:${entry.value }<br/>
       </z:foreach>
      
       <%
           Integer num[]={1,2,3,4};
           request.setAttribute("num",num);
        %>
       <z:foreach var="i" items="${num}">
           ${i }  
       </z:foreach>
      
  </body>
 
</html>

我们修改我们之前的标签处理器类:
package org.zyg.web.exampleTag;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class ForeachTag extends SimpleTagSupport {
    //传入数组、Map、List都有可能,所以用Object来接收参数
    private Object items;
    private String var;
    private Collection collection;
    
    //在设置items参数的时候对类型进行转换,不管是什么都转换成单列的Collection
    public void setItems(Object items) {
        this.items = items;
        //首先判断传递进来的数据是不是一个Collection
        if(items instanceof Collection){ //list set(单列)
            collection = (Collection)items;
        }
        
        if(items instanceof Map){
            Map map=(Map)items;
            collection=  map.entrySet();//双列改成了单列的set
        }
        
        if(items instanceof Object[]){
            Object[] obj=(Object[])items;
            collection=Arrays.asList(obj);//将数组转换成单列的list
        }
    }
    
    public void setVar(String var) {
        this.var = var;
    }

    @Override
    public void doTag() throws JspException, IOException {
        //对集合进行迭代
        Iterator it=collection.iterator();
        while(it.hasNext()){
            Object value=it.next();
            //将迭代的值放入PageContext中的var值下
            this.getJspContext().setAttribute(var, value);
            //将标签体显示在页面上
            this.getJspBody().invoke(null);
        }
    }
}

标签之前已经在z.tld中注册过了,这里不再注册。

然后重启Web应用,观察效果:
【自定义标签开发】09-标签案例-开发foreach标签_第1张图片
发现我们3种类型的数据都迭代出来了。

那么我们能不能迭代8种基本数据类型呢?我们试一下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="/example" prefix="z" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Hello</title>
  </head>
 
  <body>
      
      <%
          List<String> list=new ArrayList<String>();
          list.add("张三");
          list.add("李四");
          list.add("王五");
          request.setAttribute("nameList",list);
       %>
       <z:foreach var="str" items="${nameList}">
           姓名:${str}<br/>
       </z:foreach>
      
       <%
          Map<String,String> map=new HashMap<String,String>();
          map.put("总部","上海");
          map.put("分销处","广州");
          map.put("人力资源部","深圳");
          map.put("销售部","北京");
          request.setAttribute("localmap",map);
       %>
       <z:foreach var="entry" items="${localmap}">
           ${entry.key}:${entry.value }<br/>
       </z:foreach>
      
       <%
           Integer num[]={1,2,3,4};
           request.setAttribute("num",num);
        %>
       <z:foreach var="i" items="${num}">
           ${i }  
       </z:foreach>
       <br/>
      
       <p>int类型数组迭代</p>
     <%
         int num2[]={1,2,3,4};
         request.setAttribute("num2",num2);
      %>
     <z:foreach var="i" items="${num2}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>double类型数组迭代</p>
     <%
         double num3[]={1.12,2.312,3.123123,4.03};
         request.setAttribute("num3",num3);
      %>
     <z:foreach var="i" items="${num3}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>float类型数组迭代</p>
     <%
         float num4[]={1.22f,2.123f,3.1f,4.21f};
         request.setAttribute("num4",num4);
      %>
     <z:foreach var="i" items="${num4}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>char类型数组迭代</p>
     <%
         char num5[]={'l','o','v','e'};
         request.setAttribute("num5",num5);
      %>
     <z:foreach var="i" items="${num5}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>short类型数组迭代</p>
     <%
         short num6[]={11,22,33,44};
         request.setAttribute("num6",num6);
      %>
     <z:foreach var="i" items="${num6}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>long类型数组迭代</p>
     <%
         long num7[]={1111111111,222222222,333333333,444444444};
         request.setAttribute("num7",num7);
      %>
     <z:foreach var="i" items="${num7}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>byte类型数组迭代</p>
     <%
         byte num8[]={'%','$','=','#'};
         request.setAttribute("num8",num8);
      %>
     <z:foreach var="i" items="${num8}">
         ${i }  
     </z:foreach>
     <br/>
    
     <p>boolean类型数组迭代</p>
     <%
         boolean num9[]={1==2,(1+2)==3,5>2,7<6};
         request.setAttribute("num9",num9);
      %>
     <z:foreach var="i" items="${num9}">
         ${i }  
     </z:foreach>
     <br/>
      
  </body>
 
</html>

刷新页面,发现报错:


报的是“空指针异常”的错误。我们看一下我们的ForeachTag的代码45行是什么:
【自定义标签开发】09-标签案例-开发foreach标签_第2张图片

说明我们的collection.iterator();为空,也就是基本数据类型的数组没有被setItems(Object items)中的判断items类型的任何判定条件所判定,所以我们要加一个判断基本数据类型数组的判断条件:
注意:这里用到了反射技术,如果不清楚这一块的,建议先学习一下。
package org.zyg.web.exampleTag;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class ForeachTag extends SimpleTagSupport {
    //传入数组、Map、List都有可能,所以用Object来接收参数
    private Object items;
    private String var;
    private Collection collection;
    
    //在设置items参数的时候对类型进行转换,不管是什么都转换成单列的Collection
    public void setItems(Object items) {
        this.items = items;
        //首先判断传递进来的数据是不是一个Collection
        if(items instanceof Collection){ //list set(单列)
            collection = (Collection)items;
        }
        
        if(items instanceof Map){
            Map map=(Map)items;
            collection=  map.entrySet();//双列改成了单列的set
        }
        
        if(items.getClass().isArray()){//判断是不是数组
            this.collection=new ArrayList();
            int length=Array.getLength(items);//得到数组长度
            for (int i = 0; i < length; i++) {
                Object value=Array.get(items, i);
                this.collection.add(value);
            }
        }
        
        /*if(items instanceof Object[]){
            Object[] obj=(Object[])items;
            collection=Arrays.asList(obj);//将数组转换成单列的list
        }*/
        
    }
    
    public void setVar(String var) {
        this.var = var;
    }

    @Override
    public void doTag() throws JspException, IOException {
        //对集合进行迭代
        Iterator it=collection.iterator();
        while(it.hasNext()){
            Object value=it.next();
            //将迭代的值放入PageContext中的var值下
            this.getJspContext().setAttribute(var, value);
            //将标签体显示在页面上
            this.getJspBody().invoke(null);
        }
    }
}
上面这段代码,就可以对任意类型的数组进行迭代,当然大家理解之后可以使用同样的方法在我们自己的工程中使用。

我们的最终效果:
【自定义标签开发】09-标签案例-开发foreach标签_第3张图片

至此,我们的完整的foreach迭代标签开发完毕。
转载请注明出处:http://blog.csdn.net/acmman/article/details/51258357

你可能感兴趣的:(jsp,标签,tag,迭代,SimpleTag)