明月松間照 清泉石上流


                                                  ——— 兵臨城下   貓科動物
          posts - 70, comments - 137, trackbacks - 0, articles - 23
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          學習Taglib

          Posted on 2006-11-25 16:36 兵臨城下 閱讀(331) 評論(0)  編輯  收藏 所屬分類: Java EE

          Taglib原理和實現之循環的Tag

          作者:WalkingWithJava Java研究組織 (2005-04-21 14:13:39)

          ? 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;

          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


          個人覺得不錯的一片文章,現在才知道Tag也可以這么用!學海無涯啊!

          有幾個疑問:
          1、在WithCollectionTag中為什么沒有調用doEndTag()方法,而使用了doAfterBody()?
          2、在ElementOutputTag中為什么只使用了doEndTag()方法?
          doStartTag() 、doEndTag()、doAfterBody()不知該怎么用,什么時候用哪個,不用哪個?請教了!

          還有就是下面幾個屬性,不知道該怎么用?
          SKIP_BODY???? SKIP_PAGE???????EVAL_PAGE???EVAL_BODY_BUFFERED??????
          EVAL_BODY_INCLUDE?????????? EVAL_BODY_AGAIN

          主站蜘蛛池模板: 英山县| 鄢陵县| 宜黄县| 剑阁县| 清水县| 子长县| 襄城县| 岑巩县| 元朗区| 诏安县| 南漳县| 千阳县| 武胜县| 东兰县| 青铜峡市| 明水县| 墨江| 行唐县| 吐鲁番市| 阜南县| 青铜峡市| 罗江县| 鄱阳县| 西贡区| 隆安县| 柘荣县| 高平市| 扶沟县| 故城县| 衡山县| 连云港市| 思茅市| 二手房| 虎林市| 新野县| 佛冈县| 临潭县| 金寨县| 宁国市| 新泰市| 乡城县|