JSP標籤自訂

來源:互聯網
上載者:User

最近一直在學習自訂標籤,於是就想試著去實現一些JSP中內建的標籤庫功能,順便也把反射機制複習一下。(如果你對這兩種技術不很熟悉,這篇blog的最下邊有一些關於反射和自訂標籤的example和PPT文檔下載)

今天要實現的功能是useBean標籤。下表是它的一些屬性和用途。(我只選了個比較重要的屬性,並沒有實現所有屬性)

屬性 用途
id 給將要應用bean的變數一個名字,如果發現有相同id和scope的bean對象,則應用此對象而不會產生一個新的例示。
class 指明了bean的整個包名。
scope 表 明了此bean的作用範圍,共有四個值:page, request, session, 和 application,預設的是page屬性,表明此bean只能應用於當前頁(儲存在當前頁的PageContext 中);request屬性工作表明此bean只能應用於當前的使用者請求中(儲存在ServletRequest對象中);session屬性工作表明此bean能 應用於當前HttpSession生命週期內的所有頁面;application屬性值則表明此bean能應用於共用ServletContext的所有 頁面。需要注意的是,當沒有具有相同的id和scope對象時,一個jsp:useBean 實體只能作用於一個新的例示中,反之,則作用於以前的對象,這時,在jsp:useBean標籤之間的任何jsp:setParameter和其它實體都 將被忽略。
type 說明將要索引對象的變數類型,它必須與類名及父類名相匹配。記住,這個變數的名字是由id屬性值代替的。
beanName 給定此bean的名字,可以將其提供給bean的例示方法,只提供beanName和type而忽略class屬性的情況是允許的。

 下面是標籤處理方法類:UseBean.java:

import javax.servlet.jsp.*;

import javax.servlet.jsp.tagext.*;

import java.lang.reflect.*;

//

public class UseBean extends TagSupport{  //繼承自TagSupport類

       private String scope;

       private String type;

       public UseBean(){super();}

       /**

        *設定屬性存取方法,這個方法由容器自動調用。setId()和getId()由系統自動實現

        */

       public void setScope(String s) {

           this.scope = s;

      }    

       public String getScope(){return this.scope;}

       public void setType(String type){

              this.type=type;

       }

       public String getType(){return this.type;}

       /**

        *覆蓋doStartTag方法

        */

        public int doStartTag() throws JspTagException 

        {  

            Object o = null;

           // find the bean in the specified scope

           if (scope.equals("page")) {

                     o = pageContext.getAttribute(getId(),PageContext.PAGE_SCOPE);

              } else if (scope.equals("request")) {

                     o = pageContext.getAttribute(getId(), PageContext.REQUEST_SCOPE);

              } else if (scope.equals("session")) {

                     o = pageContext.getAttribute(getId(), PageContext.SESSION_SCOPE);

              } else if (scope.equals("application")) {

                     o = pageContext.getAttribute(getId(), PageContext.APPLICATION_SCOPE);

           }

              if(o==null)

              {

                     System.out.println("o is null!");

                     try{

                            Class u=Class.forName(type);

                            o=u.newInstance();//無參構造方法

                            System.out.println("create success!");

                     }

                     catch(Exception e){

                            throw new JspTagException("error to created a "+getId()+" object!");

                     }

              }

              pageContext.setAttribute(getId(), o); //儲存執行個體對象到內容物件中

           return EVAL_BODY_INCLUDE; //傳回型別

       }

}

現 在我們已經把對象執行個體放到pageContext裡了,是不是這樣就可以在JSP頁面中直接引用了?當然不是了,直接將JAVA對象放進 pageContext中與在指令碼中直接引用是不同的。差別在於JSP容器要負責取得這個對象,以指令碼變數的形式提供給頁面。即JSP容器負責來維護指令碼 變數與pageContext中相應對象的狀態。有兩種方法可以為自訂標籤來聲明指令碼變數。

一種是聲明variable,一種是通過TagExtraInfo類聲明變數。前者是JDK1.2後的方法,優點是比較方便。後者因為要再寫一個類檔案,所以顯得麻煩些,但更靈活,出於相容性與功能上的考慮,建議還是採用後者。(關於此類的詳細說明,請參考PPT文檔)

 import javax.servlet.jsp.*;

import javax.servlet.jsp.tagext.*;

 public class UseBeanTag extends TagExtraInfo {

    public VariableInfo[] getVariableInfo(TagData data) {

        return new VariableInfo[] {

      new VariableInfo(

            data.getId(),

           data.getAttributeString("type"),

            true,

            VariableInfo.AT_BEGIN)

        };

  }

}

 

現在,定義一個useBean標籤的工作已進行大半,下面該定義標籤庫描述(TLD)檔案了,該檔案是一個XML文檔,主要定義標籤的屬性、處理類和擴充資訊類的聲明。主要聲明部分如下:(tag.tld)

……………………(省去標題部分)

<!-- useBEAN 標籤-->

 <tag>

<name>useBEAN</name>

<!—聲明標籤處理類-->

    <tag-class>cn.dever.tag.UseBean</tag-class>

<!—聲明標籤擴充資訊類-->

    <tei-class>cn.dever.taginfo.UseBeanTag</tei-class>

    <!—主體內容類型-->

    <body-content>jsp</body-content>

<!—屬性設定-->

   <attribute>

        <name>scope</name>

<!—是否必選-->

        <required>true</required>

<!—是否可以使用JSP運算式-->

        <rtexprvalue>true</rtexprvalue>

      </attribute>

   

      <attribute>

        <name>id</name>

        <required>true</required>

        <rtexprvalue>true</rtexprvalue>

      </attribute>

   

      <attribute>

        <name>type</name>

        <required>true</required>

        <rtexprvalue>true</rtexprvalue>

      </attribute>

 </tag>

其實這個標籤庫描述檔案應該是最先建立的,因為我們主要是為了說明實現的方法,所以標籤描述放在後邊了。接下就是將剛才做的這些東西部署到我們的應用中去。在目標JSP頁面中引用一下就OK了。

<%@ taglib uri="/WEB-INF/tag.tld" prefix="dever" %>

<dever:useBEAN id="test" type="cn.dever.common.User" scope="page" />

OK,到此為止,我們自訂的useBean標籤已經可以開始工作了,是不是覺得很容易,其實本來就不難,只要大家掌握了定義標籤的流程和配置方法,剩下的就只是寫標籤處理類了,在以後的幾篇blog中,我就不再詳述這些部署和配置,直接給出標籤處理類的代碼。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.