明月松間照 清泉石上流


                                                  ——— 兵臨城下   貓科動(dòng)物
          posts - 70, comments - 137, trackbacks - 0, articles - 23
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          學(xué)習(xí)Taglib

          Posted on 2006-11-25 16:36 兵臨城下 閱讀(327) 評(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

          主站蜘蛛池模板: 邵东县| 松溪县| 棋牌| 屏东市| 孟州市| 永清县| 古交市| 阜宁县| 建瓯市| 如东县| 马边| 吴川市| 南通市| 左云县| 双桥区| 东宁县| 瑞丽市| 社旗县| 花莲市| 即墨市| 天水市| 和平区| 富宁县| 土默特左旗| 且末县| 上饶县| 措勤县| 武安市| 宁津县| 固安县| 运城市| 沽源县| 建湖县| 兖州市| 普格县| 合水县| 罗平县| 黑水县| 五指山市| 桃江县| 武宁县|