隨筆-26  評論-13  文章-46  trackbacks-0

          JSP中自定義標記符的使用

                                         

          摘要

             在JSP有一種機制,可以讓你在JSP頁面中插入與HTML類似的標記。本文介紹JSP定制標記的基本概念和構成,以及如何開發和應用JSP定制標記。

           關鍵字

          JSP,XMLTLD,標記符

          什么是標記

          使用HTML語言我們可以這樣去編輯我們的網頁:

             <HTML> 

              
          <HEAD> 

          <TITLE> 

           HELLO  WORLD 

          </TITLE> 

                  
          </HEAD> 

                  
          <BODY> 

          HELLO WORLD 

          </BODY> 

          </HTML> 

          在這里我們把</HEAD>,<TITLE>,<BODY>稱為標記。HTML 標記( HTML Markup)是HTML文檔的控制語言,用于指定瀏覽器顯示和打印文檔的方式.它是用小于號"<"和大于號">"括起來的短語和符號,如<Html>、</Body>等。許多HTMl標記以成對的方式出現,如<TITLE></TITLE>、<Body></Body> 等。在JSP中我們也可以定制自己的標記,以供JSP頁面使用,如下例所示

          <!—login.jsp--> 

          <%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %> 

          <html> 

                
          <head> 

                     
          <title>login</title> 

                
          </head> 

                
          <body> 

                  
          <tagclass:login width="200" height= "100" > 

                     
          </tagclass:login> 

                
          </body> 

          </html> 

          在上例中</tagclass:login>就是一個JSP定制標記符。widtht、height是這個標記的屬性。<%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>是一個標記庫定義指令,在稍后我們將會討論。在JSP中定制標記符,實質上就是以標記的形式封裝了一個俱有獨立功能的Java類。標記的使用減少了直接嵌入JSP頁面的Java代碼,方便了頁面的布局,并且有利于代碼的復用,提高了開發的效率。

          JSP服務器解析標記的過程

          那么當一個標記被嵌入JSP頁面后,JSP服務器是如何對這個標記進行解析的呢?下面讓我們一起看一下它的順序圖:

           

          圖中各對象的含義如下所示:

          Client   表示客戶端。

          JSP-ServerJSP服務器。

          JSP-PageJSP頁面。

          TLD   標記庫描述文件,定義標記和標記的各種屬性和處理文件等。

          TagClass   標記處理程序

          當一個用戶訪問一個JSP頁面時,這個請求被發送到JSP服務器,JSP服務器會根據這個請求去調用相應的頁面,如果這個頁面中有自定義的標記,JSP服務就會根據頁面指令<%@ taglib>去訪問TLD得到處理程序的相關信息,接著調用該處理程序的構造器方法,啟動標記符處理程序,并讀取標記符的屬性和相應值。對每個沒有設置屬性的,調用相應的set方法。當標記符第一次使用時,它的任何屬性都不會做過設置,因此對每個屬性都調用set方法。屬性設置完以后,JSP服務器調用處理程序的doStartTag(),然后再調用doEndTag()方法。最后JSP服務器會繼續處理剩下的頁面,在頁面結尾調用release()方法,清理占用的所有資源。

          TLD文件

          TLD(TLD:Tag Library Descriptor標記庫描述符)文件,標準的XML格式的標記定義文件,被用來存放標記符的信息,下面就是一個典型的TLD文件。

          <?xml version="1.0" encoding="ISO-8859-1" ?>

          <!—XML的版本及其字符集-->

           

           

          <!DOCTYPE taglib

                PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

               "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

          <!—文檔類型定義-->

           

           

          <taglib>

          <!—此標記說明我們開始描述一個標記庫-->

           

           

            <tlibversion>1.0</tlibversion>

           <!—標記庫的版本-->

           

           

            <jspversion>1.1</jspversion>

           <!—所使用的JSP的版本-->

           

           

           <shortname>tagclass</shortname>

           <!—缺省的名稱-->

           

           

            <tag>

               <name>login</name>

              <!—標記的名稱-->

           

           

          <tagclass>

          tagclass.login.login

          <!—處理這個Tag的相應的類的名稱-->

           

          </tagclass>

               <info>

                <!—對本標記符的描述-->

           

               </info>

          <attribute>

          <!—開始定義標記的屬性-->

           

                    <name>height</name>

                 <!—屬性的名稱-->

           

                    <required>true</required>

                 <!—表示這個屬性是不是必須的-->

           

                    <rtexprvalue>true</rtexprvalue>

          <!—表示這個屬性是否可以用JSP的程序段的結果輸出-->

                </attribute>

          <attribute>

                    <name>width</name>

                    <required>true</required>

                    <rtexprvalue>true</rtexprvalue>

                </attribute>

              </tag>

          </taglib>

          在這個TLD文件中定義了只有一個標記符的標記符庫,這個名為login的標記符會調用一個Applet以驗證用戶的合法性。處理這個標記的類就是tagclass.login.login。width、height是這個標記的兩個屬性。屬性是在使用標記符時作為參數發送的值。我們可以在上面的示例中增加幾個標記,也可以為每個標記添加幾個屬性。我們開發標記符庫時不一定非要從頭開始,自己編寫一個全新TLD。我們可以使用某個集成的開發的環境,也可以修改上面的例子。

          TagLib指令

          那么當JSP服務器在解析一個標記符時,它是如何定義一個標記庫的呢?這就是TagLib指令的主要責任。

          Taglib 指令

          定義一個標記庫以及其自定義標記的前綴.

          JSP 語法

          <%@ taglib uri="URIToTagLibrary" prefix="tagPrefix" %>

          例子
          <%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>

          <html>

                <head>

                     <title>login</title>

                </head>

                <body>

                  <tagclass:login width="200" height= "100" >

                     </tagclass:login>

                </body>

          </html>

          描述

          <% @ taglib %>指令聲明此JSP文件使用了自定義的標記,同時引用標記庫,

          也指定了他們的標記的前綴。 你必須在使用自定義標記之前使用<% @ taglib %>指令。

          屬性

          uri="URIToTagLibrary" :Uniform Resource Identifier (URI)根據標記的前綴對自定義的標記進行唯一的命名,URI可以是一個相對或絕對的路徑。
            prefix="tagPrefix":在自定義標記之前的前綴。如上例中的</tagclass:login>

          標記符的處理程序(Tag handle)

          我們還是以一個例子來看下如何實現一個Tag handle。首先是看一下它的類圖:

           

          讓我們再看一下它的代碼:

          package  tagclass.login;

          import javax.servlet.jsp.tagext.TagSupport;

          import javax.servlet.jsp.*;

          import java.io.*;

          public class login extends TagSupport

          {

                public login()

               {

                       super();

                }

                public int doStartTag() throws JspTagException

               {

                          JspWriter out = pageContext.getOut();

                          try

                          {

                                  out.println("<APPLET CODEBASE=applet/login/ CODE=login.class width=200 height=100 > </APPLET>");

          }

                          catch(Exception e)

                          {

           

                          }

                       return SKIP_BODY;

          }

          publicc int doEndTag()throws JsptagException

          {

               return EVAL_PAGE;

          }

                 public void release()

                 {

                           super.release();

                 }

                public void setWidth(String language)

                {

                       this.width = width;

                }

                public String getWidth()

                {

                       return this.width;

                }

                public void setHeight(String height)

                {

                    this.height=height;

                }

                public String getHeight()

                {

                    return this.height;

                }

                private String width;

                private String height;

           }

          從以上我們可以看出,實現一個簡單的標記符處理程序有幾個要求:①增加一個類,使之繼承java.Servlet.jsp.tagext.TagSupport類。這個類提供了java.Servlet.jsp.tagext.Tag接口所要求的所有的方法。另外,還需要使用一些基本的API,使JSP容器能夠調用我們自己提供的標記符處理程序。②必須為每個標記符屬性分別創建一個get<attribute>和set<attribute>方法,JSP容器需要使用這些方法處理程序傳遞參數。③要為標記符處理程序創建一個構造器和自毀器。JSP需要使用構造器啟動處理程序。自毀器是在realease()方法中定義的。在處理程序的生命周期結束時,需要調用自毀器釋放所占用的資源。④創建兩個名為doStartTag()和doEndTag()的方法,執行具體的處理和輸出動作。這兩個方法是在處理自定義標記符的起始位置和結束位置調用的。它們的返回值是在Tag Interface里定義的靜態int,這幾個靜態值分別是:

          SKIP_BODY隱含0  :跳過了開始和結束標簽之間的代碼。

          EVAL_BODY_INCLUDE隱含1:將body的內容輸出到存在的輸出流中

          SKIP_PAGE隱含5 : 忽略剩下的頁面。

          EVAL_PAGE隱含6:繼續執行下面的頁

            當然標記符也有它自己的缺點。很不方便的封裝過程,有限的功能。對于一些不太復雜和功能單一的邏輯描述,需要傳遞的參數要求不高時,使用JSP標記,要方便的多。對于大多數的商業邏輯應用,還是使用bean要好的多,也宜于servlet控制。

          附錄:文章中所用示例的完整代碼

          JSP代碼:login.jsp

          <%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>

          <html>

               <head>

                     <title></title>

               </head>

               <body>

                     <tagclass:login width="200" height= "100" >

                     </tagclass:login>

               </body>

          </html>

          標記符描述庫:taglib.tld

          <?xml version="1.0" encoding="ISO-8859-1" ?>

          <!DOCTYPE taglib

                PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

               "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

          <taglib>

            <tlibversion>1.0</tlibversion>

            <jspversion>1.1</jspversion>

           <shortname>tagclass</shortname>

            <tag>

               <name>login</name>

          <tagclass>

          tagclass.login.login

          </tagclass>

               <info>

              </info>

          <attribute>

                    <name>height</name>

                    <required>true</required>

                    <rtexprvalue>true</rtexprvalue>

                </attribute>

          <attribute>

                    <name>width</name>

                    <required>true</required>

                    <rtexprvalue>true</rtexprvalue>

                </attribute>

              </tag>

          </taglib>

          標記符處理程序:login.java

          package  tagclass.login;

          import javax.servlet.jsp.tagext.TagSupport;

          import javax.servlet.jsp.*;

          import java.io.*;

          public class login extends TagSupport

          {

                public login()

               {

                       super();

                }

                public int doStartTag() throws JspTagException

               {

                          JspWriter out = pageContext.getOut();

                          try

                          {

                                  out.println("<APPLET CODEBASE=applet/login/ CODE=login.class width=200 height=100 > </APPLET>");

          }

                          catch(Exception e)

                          {

           

                          }

                       return SKIP_BODY;

          }

          publicc int doEndTag()throws JsptagException

          {

               return EVAL_PAGE;

          }

                 public void release()

                 {

                           super.release();

                 }

                public void setWidth(String language)

                {

                       this.width = width;

                }

                public String getWidth()

                {

                       return this.width;

                }

                public void setHeight(String height)

                {

                    this.height=height;

                }

                public String getHeight()

                {

                    return this.height;

                }

                private String width;

                private String height;

           }

          標記符處理程序中所使用的Applet : login.java

          import java.awt.*;

          import java.awt.event.*;

          import java.applet.*;

          public class login extends Applet implements ActionListener

          {

              private String s_username;

              private String s_userpassword;

              private Button b_ok;

              private Button b_register;

              private Label l_username;

              private Label l_userpassword;

              private TextField t_username;

              private TextField t_userpassword;

              private GridLayout g_gridlayout;

              public void init()

              {

                 b_ok=new Button("ok");

                 b_register=new Button("register");

                 l_username= new Label("name");

                 l_userpassword=new Label("password");

                 t_username=new TextField();

                 t_userpassword=new TextField();

                 b_ok.addActionListener(this);

                 b_register.addActionListener(this);

                 g_gridlayout=new GridLayout(3,2,10,10);

                 this.setLayout(g_gridlayout);

                          //this.setBackground(Color.blue);

                          add(l_username);

                          add(t_username);

                 add(l_userpassword);

                 add(t_userpassword);

                 add(b_ok);

                 add(b_register);

              }

              public void actionPerformed(ActionEvent ev)

              {

                     String s_label=ev.getActionCommand();

                     if (s_label.equals("ok"))

                     {

                           t_username.setText("name");

                     }

                     if (s_label.equals("register"))

                     {

                           t_userpassword.setText("password");

                     }

              }

              public void paint(Graphics g)

              {

               }

          }

          posted on 2005-06-07 16:17 似水流年 閱讀(327) 評論(0)  編輯  收藏 所屬分類: JSP/Servlet
          主站蜘蛛池模板: 西吉县| 万宁市| 伊春市| 佛教| 安溪县| 滕州市| 湘乡市| 泾阳县| 贵州省| 垫江县| 鹤岗市| 虎林市| 三穗县| 德昌县| 永和县| 乌恰县| 郯城县| 都兰县| 九江县| 潼关县| 嘉兴市| 安塞县| 沭阳县| 金沙县| 曲阳县| 涟源市| 福贡县| 青海省| 南岸区| 金沙县| 乐业县| 罗甸县| 揭东县| 太谷县| 湘西| 祁连县| 嘉禾县| 连城县| 百色市| 武义县| 辽中县|