Taglib原理和实现之循环的Tag

  • 来源: 互联网 作者: 若水   2008-05-05/15:09
  • 1、问题:在request里的 People 对象,有个属性叫 men ,men 是一个Collection ,有许多个man 。现在,把 collection里的man的名字都显示出来。

    显然,这是一个嵌套Tag的问题。有三个Tag互相作用:最外层的Tag找到People对象,中间的Tag取得Collection,子Tag负责打印。

    例如:

    <diego:withObject value="${people}">
    <diego:withCollection property="men">
    <diego:elementout property="name"/>
    </diego:withCollection>
    </diego:withObject>

    思路如下:

    1) 编写WithObjectTag,负责从El表达式中取得对象

    2) 编写WithCollectionTag,负责从对象中取得 Collection ,遍历 Collection ,每遍历一次 Collection ,执行一次body

    3) 编写ElementoutTag ,把 Collection 中每个men对象的 name 打印出来

    2. 完整程序如下:

    在上例的diegoyun.vo包内,编写 People 类

    package diegoyun.vo;
    import java.util.Collection;
    public class People
    {
    private Collection men = null;
    public Collection getMen()
    {
    return men;
    }
    public void setMen(Collection men)
    {
    this.men = men;
    }
    }

    编写 withObject ,这是从request里取得People对象的最外层Tag

    package diegoyun;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.BodyTagSupport;
    import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
    public class WithObjectTag extends BodyTagSupport
    {
    private Object value = null;

    public Object getValue()
    {
    return value;
    }
    public void setValue(Object value)throws JspException
    {
    this.value = ExpressionEvaluatorManager.evaluate("value", value.toString(), Object.class, this, pageContext);
    }
    public int doStartTag()
    {
    return EVAL_BODY_INCLUDE;
    }
    public int doEndTag()throws JspException
    {
    return EVAL_PAGE;
    }
    }

    编写WithCollectionTag,该Tag负责取得Collection,并遍历执行子Tag

    package diegoyun;

    import java.util.Collection;
    import java.util.Iterator;

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

    import org.apache.commons.beanutils.PropertyUtils;

    public class WithCollectionTag extends BodyTagSupport {
    private Object element = null;

    private Collection list = null;

    private Iterator iterator = null;

    public Object getElement() {
    return element;
    }

    public void setProperty(String property) throws JspException {
    //取得父Tag对象,并且得到Collection
    WithObjectTag parent = (WithObjectTag) getParent();
    if (parent == null)
    throw new JspException("parent tag is null");
    try {
    Object propertyValue = PropertyUtils.getProperty(parent.getValue(),property);
    this.list = (Collection) propertyValue;
    if (list == null)
    throw new JspException("Collection is null");
    } catch (Exception e) {
    throw new JspException(e);
    }
    }

    public int doStartTag() throws JspException {
    //设置第一个元素,然后执行子Tag
    iterator = list.iterator();
    if (iterator.hasNext())
    element = iterator.next();
    return EVAL_BODY_INCLUDE;
    }

    public int doAfterBody() {
    if (iterator.hasNext()) {
    //如果还存在子元素,设置子元素,并且再次执行子Tag
    //循环由此而来
    //否则不再执行子Tag
    element = iterator.next();
    return EVAL_BODY_AGAIN;
    }
    else
    return EVAL_PAGE;
    }
    }

    编写 ElementOutputTag

    package diegoyun;
    import java.io.IOException;

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

    import org.apache.commons.beanutils.PropertyUtils;
    #p#分页标题#e#
    public class ElementOutputTag extends TagSupport
    {
    private Object propertyValue = null;
    public void setProperty(String property)throws JspException
    {
    WithCollectionTag parent = (WithCollectionTag)getParent();
    if(parent == null)
    throw new JspException("parent tag is null");
    try
    {
    //判断上层tag中是否存在该属性名称,如果存在,取得属性值,否则报错
    propertyValue = PropertyUtils.getProperty(parent.getElement(), property);
    }
    catch (Exception e)
    {
    throw new JspException(e);
    }
    }
    public int doEndTag()throws JspException
    {
    try
    {
    //简单的把值打印到jsp页面
    pageContext.getOut().print(propertyValue);
    }
    catch (IOException e)
    {
    throw new JspException(e);
    }
    return EVAL_PAGE;
    }
    }

    编写tld

    <!--WithObjectTag-->
    <tag>
    <name>withObject</name>
    <tag-class>diegoyun.WithObjectTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
    <name>value</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>
    <!--WithCollectionTag-->
    <tag>
    <name>withCollection</name>
    <tag-class>diegoyun.WithCollectionTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
    <name>property</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>
    <!--ElementOutputTag-->
    <tag>
    <name>elementout</name>
    <tag-class>diegoyun.ElementOutputTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
    <name>property</name>
    <required>false</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    </tag>

    编写jsp

    <%@ page language="java" %>
    <%@ page import="diegoyun.vo.*"%>
    <%@ page import="java.util.*"%>
    <%@ taglib uri="/WEB-INF/tlds/diego.tld" prefix="diego"%>

    <html>
    <body bgcolor="#FFFFFF">
    <%
    Collection c = new ArrayList();

    Man man1 = new Man();
    man1.setName("diego");
    c.add(man1);

    Man man2 = new Man();
    man2.setName("Zidane");
    c.add(man2);

    Man man3 = new Man();
    man3.setName("Rui");
    c.add(man3);

    People p =new People();
    p.setMen(c);
    request.setAttribute("people",p);
    %>
    Test loop tag:
    <br>
    <diego:withObject value="${people}">
    <diego:withCollection property="men">
    <diego:elementout property="name"/>
    <br>
    </diego:withCollection>
    </diego:withObject>
    </body>
    </html>

    运行,则可以看到:

    Test loop tag:
    diego
    Zidane
    Rui

    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多