Posted on 2006-11-25 16:36
兵臨城下 閱讀(326)
評(píng)論(0) 編輯 收藏 所屬分類:
Java EE
Taglib原理和實(shí)現(xiàn)之循環(huán)的Tag
|
作者:WalkingWithJava Java研究組織 (2005-04-21 14:13:39)
|
|
|
?
1、問(wèn)題:在request里的 People 對(duì)象,有個(gè)屬性叫 men ,men 是一個(gè)Collection ,有許多個(gè)man 。現(xiàn)在,把 collection里的man的名字都顯示出來(lái)。
顯然,這是一個(gè)嵌套Tag的問(wèn)題。有三個(gè)Tag互相作用:最外層的Tag找到People對(duì)象,中間的Tag取得Collection,子Tag負(fù)責(zé)打印。
例如:
<diego:withObject value="${people}"> <diego:withCollection property="men"> <diego:elementout property="name"/> </diego:withCollection> </diego:withObject> |
思路如下:
1) 編寫WithObjectTag,負(fù)責(zé)從El表達(dá)式中取得對(duì)象
2) 編寫WithCollectionTag,負(fù)責(zé)從對(duì)象中取得 Collection ,遍歷 Collection ,每遍歷一次 Collection ,執(zhí)行一次body
3) 編寫ElementoutTag ,把 Collection 中每個(gè)men對(duì)象的 name 打印出來(lái)
2. 完整程序如下:
在上例的diegoyun.vo包內(nèi),編寫 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對(duì)象的最外層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負(fù)責(zé)取得Collection,并遍歷執(zhí)行子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對(duì)象,并且得到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 { //設(shè)置第一個(gè)元素,然后執(zhí)行子Tag iterator = list.iterator(); if (iterator.hasNext()) element = iterator.next(); return EVAL_BODY_INCLUDE; }
public int doAfterBody() { if (iterator.hasNext()) { //如果還存在子元素,設(shè)置子元素,并且再次執(zhí)行子Tag //循環(huán)由此而來(lái) //否則不再執(zhí)行子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;
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中是否存在該屬性名稱,如果存在,取得屬性值,否則報(bào)錯(cuò) propertyValue = PropertyUtils.getProperty(parent.getElement(), property); } catch (Exception e) { throw new JspException(e); } } public int doEndTag()throws JspException { try { //簡(jiǎn)單的把值打印到j(luò)sp頁(yè)面 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> |
運(yùn)行,則可以看到:
Test loop tag: diego Zidane Rui |
個(gè)人覺(jué)得不錯(cuò)的一片文章,現(xiàn)在才知道Tag也可以這么用!學(xué)海無(wú)涯啊!
有幾個(gè)疑問(wèn): 1、在WithCollectionTag中為什么沒(méi)有調(diào)用doEndTag()方法,而使用了doAfterBody()? 2、在ElementOutputTag中為什么只使用了doEndTag()方法? doStartTag() 、doEndTag()、doAfterBody()不知該怎么用,什么時(shí)候用哪個(gè),不用哪個(gè)?請(qǐng)教了!還有就是下面幾個(gè)屬性,不知道該怎么用? SKIP_BODY???? SKIP_PAGE???????EVAL_PAGE???EVAL_BODY_BUFFERED?????? EVAL_BODY_INCLUDE?????????? EVAL_BODY_AGAIN |