标签体除了可以执行一次简单标签外,还可以通过定义执行多次循环标签。下面以循环输出本次http请求中的所有header信息为例详细讲解自定义循环标签的过程:
1. 写一个类继承自AbstractTag,如下所示:
package com.zving.example;
import java.util.ArrayList;
import java.util.List;
import com.zving.framework.Current;
import com.zving.framework.collection.Mapx;
import com.zving.framework.template.AbstractTag;
import com.zving.framework.template.TagAttr;
/**
* @author 王育春
* @mail wyuch@zving.com
* @date 2014-1-27
*/
public class HeaderTag extends AbstractTag {
private Mapx headers;
private int i;
@Override
public String getName() {
return "Header标签";
}
@Override
public String getDescription() {
return "循环输出本次HTTP请求中的所有header项";
}
@Override
public String getPluginID() {
return ExamplePlugin.ID;
}
@Override
public String getPrefix() {
return "c";
}
@Override
public String getTagName() {
return "header";
}
/**
* 返回支持的标签属性列表
*/
@Override
public List getTagAttrs() {
ArrayList attrs = new ArrayList();
return attrs;
}
public int doStartTag() {
headers = Current.getRequest().getHeaders();
i = 0;
prepareVariable();
return AbstractTag.EVAL_BODY_BUFFERED;
}
public int doAfterBody() {
i++;
if (i >= headers.size()) {
getPreviousOut().print(getBody());// 将本次执行的结果输出到页面(或父标签的缓冲区)
return AbstractTag.EVAL_PAGE;
} else {
prepareVariable();
return AbstractTag.EVAL_BODY_AGAIN;// 再次执行标签体
}
}
private void prepareVariable() {
pageContext.addDataVariable("i", i);
pageContext.addDataVariable("name", headers.keyArray().get(i));
pageContext.addDataVariable("value", headers.valueArray().get(i));
}
}
其中doStartTag()方法返回AbstractTag.EVAL_BODY_BUFFERED表示将本标签的输出放到缓冲区,在后续方法中可以将缓冲区中的文本直接输出到页面或父标签的缓冲区,也可以对缓冲区中的文本进行修改(例如替换)后再输出,还可以不输出直接清空。
doAfterBody()根据数据的实际情况决定返回EVAL_BODY_AGAIN还是EVAL_PAGE,如果是EVAL_BODY_AGAIN则再次执行标签体,然后再标签体执行完成后再次调用doAfterBody(),周而复始不停循环,直至数据被改变从而满足返回EVAL_PAGE的条件后终止。
一般一个标签的执行周期会有三个方法被调用,按先后顺序分别是doStartTag()、doAfterBody()、doEndTag(),其中doStartTag()会在标签体未开始执行之前执行;doAfterBody()会在标签体执行完成后执行,所有谓标签体执行完成是指标签体内的文本、表达式、子标签都依次执行完成;doEndTag()会在整个标签执行完成后再执行,对于循环标签则会在循环终止后执行。
2. 将这个类作为一个扩展项注册到com.zving.framework.ui.zhtml.ZhtmlTagService,如下图所示:
3. 编写一个zhtml页面,如下所示:
HeaderTag Test:
${i+1} : ${name} = ${value}
4. 通过浏览器访问这个页面,效果如下图: