现在的位置: 首页 > 综合 > 正文

自定义标签之 开发迭代的标签库

2012年08月09日 ⁄ 综合 ⁄ 共 4396字 ⁄ 字号 评论关闭
在没有迭代标签的时候,如果要循环输出内容到网页,我们往往这样做:

<%
    
While(iterator.hasNext())
    {
        SomeObject obj 
= (SomeObject)iterator.Next();
        out.println(obj.getComeValue());
    }
%>

上面的while就是一个迭代,如果我们要开发出这样的标签,一般需要二个开发类,一具类实现BodyTagSupport接口,另一个类扩展TagExtraInfo类。TagExtraInfo旨在提供标签运行时的信息。下面来做个实例
IterateTag.java

package eflylab;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.util.*;

public class IterateTag extends BodyTagSupport
{
    
/**
     *Tag的属性
     
*/

    
private String name;
    
//it为要迭代的对象
    private Iterator it;
    
//type表示it中对象的类型
    private String type;

    
/**
     *设置属性collection
     
*/

    
public void setCollection(Collection collection)
    
{
        
if(collection.size()>0)
        it
=collection.iterator();
    }

    
public void setName(String name)
    
{
        
this.name=name;
    }

    
public void setType(String type)
    
{
        
this.type=type;
    }

    
/**
     *如果it属性为null,那么忽略计算tagbody。
     
*/

    
public int doStartTag()throws JspTagException
    
{
        
if(it==null)
            
return SKIP_BODY;
        
else
            
return continueNext(it);
    }

    
    
public int doAfterBody()throws JspTagException
    
{
        
return continueNext(it);
    }

    
    
public int doEndTag()throws JspTagException
    
{
        
try
        
{
            
if(bodyContent!=null)
            bodyContent.writeOut(bodyContent.getEnclosingWriter());
        }

        
catch(java.io.IOException e)
        
{
        }

        
        
return EVAL_PAGE;
    }

    
/**
     *保护方法,用于把it.next()设置为pagecontext的属性
     
*/

    
protected int continueNext(Iterator it)throws JspTagException
    
{
        
if(it.hasNext())
        
{
            pageContext.setAttribute(name,it.next(),PageContext.PAGE_SCOPE);
            
return EVAL_BODY_TAG;
        }

        
else
        
{
            
return SKIP_BODY;
        }

    }

}

由于BodyTagSupport类实现了IteratorTag接口,所以在开发迭代标签时,可以直接从BodyTagSupport类继承,IterateTag就是从BodyTagSupport类继承的例子。在IterateTag中,有3个属性,它们是name,type和it。name代表了在pageContext中标识的一个属性的名字;type代表了待迭代的内容的类型;it代表了要迭代的内容。在IterateTag中必须提供这些属性的setter方法,并且在JSP中使用这些属性时必须提供对应的值。
在doStartTag方法中,如果it不为null,那么就进行第一次迭代。在continueNext方法中如果it还有下一个,那么就继续迭代,如果没有下一个了,就返回SKIP_BODY,表示不再迭代。
除了上面的标签类外,还需要开发一个表示标签信息的类,如下
iterateTEI.java

package eflylab;
import javax.servlet.jsp.tagext.*;
//TagExtraInfo用于提供一些在标签翻译时相关的信息。
public class IterateTEI extends TagExtraInfo
{
    
public IterateTEI()
    
{
        
super();
    }

    
    
public VariableInfo[] getVariableInfo(TagData data)
    
{
        
return new VariableInfo[]
        
{
            
new VariableInfo(
                data.getAttributeString(
"name"),
                data.getAttributeString(
"type"),
                
true,
                VariableInfo.NESTED
            ),
        }
;
    }

}

需要说明的是VariableInfo的几个参数,如下:
NESTED  标签中的参数在starttag到endtag之间是有效的。
AT_BEGIN  标签中的参数在标签的开始到JSP结束是有效的。
AT_END  标签中的参数在标签的结束到JSP页面的结束是有效的。

当然另外在标签的描述文件TLD中要加上这二类的描述

<tag>
      
<name>iterate</name>
      
<tag-class>eflylab.IterateTag</tag-class>
      
<tei-class>eflylab.IterateTEI</tei-class>
      
<body-content>jsp</body-content>
      
<attribute>
          
<name>collection</name>
          
<required>true</required>
          
<rtexprvalue>true</rtexprvalue>
      
</attribute>
      
<attribute>
          
<name>name</name>
          
<required>true</required>
      
</attribute>
      
<attribute>
          
<name>type</name>
          
<required>true</required>
      
</attribute>
  
</tag>

测试代码:

Company .java
Contact .java

抱歉!评论已关闭.