javaweb學習總結(二十五)——jsp簡單標籤開發(一)

來源:互聯網
上載者:User

標籤:

javaweb學習總結(二十五)——jsp簡單標籤開發(一)一、簡單標籤(SimpleTag)

  由於傳統標籤使用三個標籤介面來完成不同的功能,顯得過於繁瑣,不利於標籤技術的推廣, SUN公司為降低標籤技術的學習難度,在JSP 2.0中定義了一個更為簡單、便於編寫和調用的SimpleTag介面來實現標籤的功能。

  

實現SimpleTag介面的標籤通常稱為簡單標籤。簡單標籤共定義了5個方法:

  • setJspContext方法
  • setParent和getParent方法
  • setJspBody方法
  • doTag方法(非常重要),簡單標籤使用這個方法就可以完成所有的商務邏輯
二、SimpleTag方法介紹2.1、setJspContext方法

  用於把JSP頁面的pageContext對象傳遞給標籤處理器對象

2.2、setParent方法

  用於把父標籤處理器對象傳遞給當前標籤處理器對象

2.3、getParent方法

用於獲得當前標籤的父標籤處理器對象

2.4、setJspBody方法

  用於把代表標籤體的JspFragment對象傳遞給標籤處理器對象

2.5、doTag方法

  用於完成所有的標籤邏輯,包括輸出、迭代、修改標籤體內容等。在doTag方法中可以拋出javax.servlet.jsp.SkipPageException異常,用於通知WEB容器不再執行JSP頁面中位於結束標記後面的內容,這等效於在傳統標籤的doEndTag方法中返回Tag.SKIP_PAGE常量的情況。

三、SimpleTag介面方法的執行順序

  當web容器開始執列標籤時,會調用如下方法完成標籤的初始化:

  1. WEB容器調用標籤處理器對象的setJspContext方法,將代表JSP頁面的pageContext對象傳遞給標籤處理器對象。
  2. WEB容器調用標籤處理器對象的setParent方法,將父標籤處理器對象傳遞給這個標籤處理器對象。注意,只有在標籤存在父標籤的情況下,WEB容器才會調用這個方法。
  3. 如果調用標籤時設定了屬性,容器將調用每個屬性對應的setter方法把屬性值傳遞給標籤處理器對象。如果標籤的屬性值是EL運算式或指令碼運算式,則WEB容器首先計算運算式的值,然後把值傳遞給標籤處理器對象。
  4. 如果簡單標籤有標籤體,WEB容器將調用setJspBody方法把代表標籤體的JspFragment對象傳遞進來。
  5. 執列標籤時WEB容器調用標籤處理器的doTag()方法,開發人員在方法體內通過操作JspFragment對象,就可以實現是否執行、迭代、修改標籤體的目的。
四、開發簡單標籤實現頁面邏輯

  SUN公司針對SimpleTag介面提供了一個預設的實作類別SimpleTagSupport,SimpleTagSupport類中實現了SimpleTag介面的所有方法,因此我們可以編寫一個類繼承SimpleTagSupport類,然後根據業務需要再重寫doTag方法。

4.1、控制jsp頁面某一部分內容是否執行

 編寫一個類繼承SimpleTagSupport,然後再重寫doTag方法,在doTag方法裡面不調用jspFrament.invoke方法即可。

範例程式碼如下:

SimpleTagDemo1.java

 1 package me.gacl.web.simpletag; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.PageContext; 7 import javax.servlet.jsp.tagext.JspFragment; 8 import javax.servlet.jsp.tagext.SimpleTagSupport; 9 10 /**11  * @author gacl12  * SimpleTagSupport類實現了SimpleTag介面,13  * SampleTagDemo1類繼承SimpleTagSupport14  */15 public class SimpleTagDemo1 extends SimpleTagSupport {16 17     /* 簡單標籤使用這個方法就可以完成所有的商務邏輯18      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()19      * 重寫doTag方法,控制標籤體是否執行20      */21     @Override22     public void doTag() throws JspException, IOException {23         //得到代表jsp標籤體的JspFragment24         JspFragment jspFragment = this.getJspBody();25         26         //得到jsp頁面的的PageContext對象27         //PageContext pageContext = (PageContext) jspFragment.getJspContext();28         //調用JspWriter將標籤體的內容輸出到瀏覽器29         //jspFragment.invoke(pageContext.getOut());30         31         //將標籤體的內容輸出到瀏覽器32         jspFragment.invoke(null);33         34     }35 }

  在WEB-INF目錄下建立一個simpletag.tld檔案,然後在simpletag.tld檔案中添加對該標籤處理類的描述,如下:

  

  simpletag.tld檔案代碼如下:

 1 <?xml version="1.0" encoding="UTF-8" ?> 2  3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 6     version="2.0"> 7     <!-- description用來添加對taglib(標籤庫)的描述 --> 8     <description>孤傲蒼狼開發的SimpleTag自訂標籤庫</description> 9     <!--taglib(標籤庫)的版本號碼 -->10     <tlib-version>1.0</tlib-version>11     <short-name>GaclSimpleTagLibrary</short-name>12     <!-- 13         為自訂標籤庫設定一個uri,uri以/開頭,/後面的內容隨便寫,如這裡的/simpletag ,14         在Jsp頁面中引用標籤庫時,需要通過uri找到標籤庫15         在Jsp頁面中就要這樣引入標籤庫:<%@taglib uri="/simpletag" prefix="gacl"%>16     -->17     <uri>/simpletag</uri>18     19     <!--一個taglib(標籤庫)中包含多個自訂標籤,每一個自訂標籤使用一個tag標記來描述  -->20     <!-- 一個tag標記對應一個自訂標籤 -->21      <tag>22         <description>SimpleTag(簡單標籤)Demo1</description>23         <!-- 24             為標籤處理器類配一個標籤名,在Jsp頁面中使用標籤時是通過標籤名來找到要調用的標籤處理器類的25             通過demo1就能找到對應的me.gacl.web.simpletag.SimpleTagDemo1類26          -->27         <name>demo1</name>28         <!-- 標籤對應的處理器類-->29         <tag-class>me.gacl.web.simpletag.SimpleTagDemo1</tag-class>30         <!-- 31         tld檔案中有四種標籤體類型 :empty  JSP  scriptless  tagdepentend  32             在簡單標籤(SampleTag)中標籤體body-content的值只允許是empty和scriptless,不允許設定成JSP,如果設定成JSP就會出現異常33             在傳統標籤中標籤體body-content的值只允許是empty和JSP34             如果標籤體body-content的值設定成tagdepentend,那麼就表示標籤體裡面的內容是給標籤處理器類使用的,35             例如:開發一個查詢使用者的sql標籤,此時標籤體重的SQL語句就是給SQL標籤的標籤處理器來使用的36             <gacl:sql>SELECT * FROM USER</gacl:sql>37             在這種情況下,sql標籤的<body-content>就要設定成tagdepentend,tagdepentend用得比較少,瞭解一下即可38         -->39         <body-content>scriptless</body-content>40     </tag>41 </taglib>

  在jsp頁面中匯入並使用自訂標籤,如下:

 1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp頁面中匯入自訂標籤庫 --%> 3 <%@taglib uri="/simpletag" prefix="gacl" %> 4 <!DOCTYPE HTML> 5 <html> 6   <head> 7     <title>用簡單標籤控制標籤體是否執行</title> 8   </head> 9   10   <body>11   12   <%--在jsp頁面中使用自訂標籤 demo1標籤是帶有標籤體的,標籤體的內容是"孤傲蒼狼"這幾個字串--%>13     <gacl:demo1>14         孤傲蒼狼15     </gacl:demo1>16   </body>17 </html>

  運行效果如下:

  

4.2、控制jsp頁面內容重複執行

  編寫一個類繼承SimpleTagSupport,然後再重寫doTag方法,在doTag方法裡面重複調用jspFrament.invoke方法即可。

範例程式碼如下:

SimpleTagDemo2.java

 1 package me.gacl.web.simpletag; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.JspFragment; 7 import javax.servlet.jsp.tagext.SimpleTagSupport; 8  9 /**10  * @author gacl11  * SimpleTagSupport類實現了SimpleTag介面,12  * SampleTagDemo2類繼承SimpleTagSupport13  */14 public class SimpleTagDemo2 extends SimpleTagSupport {15 16     /* 簡單標籤使用這個方法就可以完成所有的商務邏輯17      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()18      * 重寫doTag方法,控制標籤執行5次19      */20     @Override21     public void doTag() throws JspException, IOException {22         // 得到代表jsp標籤體的JspFragment23         JspFragment jspFragment = this.getJspBody();24         for (int i = 0; i < 5; i++) {25             // 將標籤體的內容輸出到瀏覽器26             jspFragment.invoke(null);27         }28     }29 }

  在WEB-INF目錄下的simpletag.tld檔案中添加對該標籤處理類的描述,如下:

1 <tag>2         <!-- 標籤名 -->3         <name>demo2</name>4         <!-- 標籤處理器類-->5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class>6         <!-- 標籤體允許的內容 ,scriptless表示標籤體的內容不允許是java指令碼代碼-->7         <body-content>scriptless</body-content>8 </tag>

  在jsp頁面中匯入並使用自訂標籤,如下:

 1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp頁面中匯入自訂標籤庫 --%> 3 <%@taglib uri="/simpletag" prefix="gacl" %> 4 <!DOCTYPE HTML> 5 <html> 6   <head> 7     <title>用簡單標籤控制標籤體執行5次</title> 8   </head> 9   10   <body>11   12   <%--在jsp頁面中使用自訂標籤 --%>13     <gacl:demo2>14         孤傲蒼狼<p/>15     </gacl:demo2>16   </body>17 </html>

  運行效果如下:

  

4.3、修改jsp頁面內容輸出

  編寫一個類繼承SimpleTagSupport,然後再重寫doTag方法,在doTag方法調用jspFrament.invoke方法時,讓執行結果寫一個自訂的緩衝中即可,然後開發人員可以取出緩衝的資料修改輸出。

範例程式碼如下:

SimpleTagDemo3.java

 1 package me.gacl.web.simpletag; 2  3 import java.io.IOException; 4 import java.io.StringWriter; 5  6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.PageContext; 8 import javax.servlet.jsp.tagext.JspFragment; 9 import javax.servlet.jsp.tagext.SimpleTagSupport;10 11 /**12  * @author gacl13  * SimpleTagSupport類實現了SimpleTag介面,14  * SampleTagDemo3類繼承SimpleTagSupport15  */16 public class SimpleTagDemo3 extends SimpleTagSupport {17 18     /* 簡單標籤使用這個方法就可以完成所有的商務邏輯19      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()20      * 重寫doTag方法,修改標籤體裡面的內容,將標籤體的內容轉換成大寫21      */22     @Override23     public void doTag() throws JspException, IOException {24         // 得到代表jsp標籤體的JspFragment25         JspFragment jspFragment = this.getJspBody();26         StringWriter sw = new StringWriter();27         //將標籤體的內容寫入到sw流中28         jspFragment.invoke(sw);29         //擷取sw流緩衝區的內容30         String content = sw.getBuffer().toString();31         content = content.toUpperCase();32         PageContext pageContext = (PageContext) this.getJspContext();33         //將修改後的content輸出到瀏覽器中34         pageContext.getOut().write(content);35     }36 }

  在WEB-INF目錄下的simpletag.tld檔案中添加對該標籤處理類的描述,如下:

1 <tag>2         <!-- 標籤名 -->3         <name>demo3</name>4         <!-- 標籤處理器類-->5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo3</tag-class>6         <!-- 標籤體允許的內容 ,scriptless表示標籤體的內容不允許是java指令碼代碼-->7         <body-content>scriptless</body-content>8 </tag>

  在jsp頁面中匯入並使用自訂標籤,如下:

 1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp頁面中匯入自訂標籤庫 --%> 3 <%--<%@taglib uri="/simpletag" prefix="gacl" %>--%> 4 <%--在jsp頁面中也可以使用這種方式匯入標籤庫,直接把uri設定成標籤庫的tld檔案所在目錄 --%> 5 <%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%> 6 <!DOCTYPE HTML> 7 <html> 8   <head> 9     <title>用簡單標籤修改jsp頁面內容輸出</title>10   </head>11   12   <body>13   14   <%--在jsp頁面中使用自訂標籤 --%>15     <gacl:demo3>16         gacl_xdp17     </gacl:demo3>18   </body>19 </html>

  運行效果如下:

  

4.4、控制整個jsp頁面是否執行

  編寫一個類繼承SimpleTagSupport,然後再重寫doTag方法,在doTag方法拋出SkipPageException異常即可,jsp收到這個異常,將忽略標籤餘下jsp頁面的執行。

範例程式碼如下:

SimpleTagDemo4.java

 1 package me.gacl.web.simpletag; 2  3 import java.io.IOException; 4 import javax.servlet.jsp.JspException; 5 import javax.servlet.jsp.SkipPageException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7  8 /** 9  * @author gacl10  * SimpleTagSupport類實現了SimpleTag介面,11  * SampleTagDemo4類繼承SimpleTagSupport12  */13 public class SimpleTagDemo4 extends SimpleTagSupport {14 15     /* 簡單標籤使用這個方法就可以完成所有的商務邏輯16      * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()17      * 重寫doTag方法,控制標籤餘下的Jsp不執行18      */19     @Override20     public void doTag() throws JspException, IOException {21         //拋出一個SkipPageException異常就可以控制標籤餘下的Jsp不執行22         throw new SkipPageException();23     }24 }

  在WEB-INF目錄下的simpletag.tld檔案中添加對該標籤處理類的描述,如下:

1 <tag>2         <!-- 標籤名 -->3         <name>demo4</name>4         <!-- 標籤處理器類-->5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo4</tag-class>6         <!-- 標籤體允許的內容 ,empty表示該標籤沒有標籤體-->7         <body-content>empty</body-content>8 </tag>

  在jsp頁面中匯入並使用自訂標籤,如下:

 1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp頁面中匯入自訂標籤庫 --%> 3 <%--<%@taglib uri="/simpletag" prefix="gacl" %>--%> 4 <%--在jsp頁面中也可以使用這種方式匯入標籤庫,直接把uri設定成標籤庫的tld檔案所在目錄 --%> 5 <%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%> 6 <!DOCTYPE HTML> 7 <html> 8   <head> 9     <title>用簡單標籤控制標籤餘下的Jsp不執行</title>10   </head>11 12   <body>13       <h1>孤傲蒼狼</h1>14        <%--在jsp頁面中使用自訂標籤 --%>15        <gacl:demo4/>16        <!-- 這裡的內容位於 <gacl:demo4/>標籤後面,因此不會輸出到頁面上 -->17        <h1>白虎神皇</h1>18   </body>19 </html>

  運行效果如下:

  

五、簡單標籤開發的一些注意細節5.1、標籤類編寫細節

  開發標籤類時,不要直接去實現SimpleTag介面,而是應該繼承SimpleTagSupport類,SimpleTagSupport類是SimpleTag介面的一個預設實作類別,通過繼承SimpleTagSupport類,就可以直接使用SimpleTagSupport類已經實現的那些方法,如果SimpleTagSupport類的方法實現不滿足業務要求,那麼就可以根據具體的業務情況將相應的方法進行重寫。

5.2、tld檔案中標籤體類型設定細節

  我們開發好一個簡單標籤後,需要在tld檔案中添加對該標籤的描述,例如:

1 <tag>2         <!-- 標籤名 -->3         <name>demo2</name>4         <!-- 標籤處理器類-->5         <tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class>6         <!-- 標籤體允許的內容 ,scriptless表示標籤體的內容不允許是java指令碼代碼-->7         <body-content>scriptless</body-content>8 </tag>

  開發好一個標籤後,在tld檔案中使用<tag>來描述一個標籤,描述的內容包括標籤名(name),標籤處理器類(tag-class),標籤體的內容(body-content)。

  tld檔案中有四種標籤體(body-content)類型 :empty、JSP、scriptless、tagdependent 

簡單標籤標籤體的細節注意問題:
     在簡單標籤(SampleTag)中標籤體body-content的值只允許是empty、scriptless、tagdependent,不允許設定成JSP,如果設定成JSP就會出現異常

1 The TLD for the class me.gacl.web.simpletag.SimpleTagDemo1 specifies an invalid body-content (JSP) for a SimpleTag

  body-content的值如果設定成empty,那麼就表示該標籤沒有標籤體,如果是設定成scriptless,那麼表示該標籤是有標籤體的,但是標籤體中的內容不可以是<%java代碼%>,例如:

1 <gacl:xdpdemo1>2    <%3            //嵌套在標籤體中的java代碼4         int i= 0;5     %>6       孤傲蒼狼7 </gacl:xdpdemo1>

  否則運列標籤時就會出現如下錯誤:

1 Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here

  jsp標籤技術出現的目的就是為了移除在jsp頁面上編寫的java代碼的,如果在jsp標籤中允許出現java代碼,那麼就違背了jsp標籤技術設計時的初衷了。所以在簡單標籤的標籤體中是不允許出現java代碼的。

傳統標籤標籤體的細節注意問題:
     在傳統標籤中標籤體body-content的值允許是empty、JSP、scriptless、tagdependentbody-content的值如果是設定成JSP那麼表示該標籤是有標籤體的,並且標籤體的內容可以是任意的,包括java代碼,如果是設定成scriptless那麼表示該標籤是有標籤體的,但是標籤體的內容不能是java代碼
    

  如果傳統標籤簡單標籤的標籤體body-content的值設定成tagdependent,那麼就表示標籤體裡面的內容是給標籤處理器類使用的,tagdependent用得比較少,瞭解一下即可

5.3、tld檔案中標籤庫的uri設定細節

  如果在一個項目中使用或者開發了多個標籤庫,例如:

  

  那麼標籤庫的uri不能設定成相同的,否則在Jsp頁面中通過uri引用標籤庫時就不知道引用哪一個標籤庫了,如果真的有那麼巧,兩個標籤庫的uri是剛好一樣的,如所示:

  

  那麼在jsp頁面中引用標籤庫時如果"<%@taglib uri="/gacl" prefix="gacl" %>"這樣引用,那麼就無法判斷當前引用的標籤庫到底是gacl.tld標籤庫中的標籤還是simpletag.tld標籤庫中的標籤,因為兩個標籤庫的uri剛好都是"/gacl",在兩個標籤庫的引用uri一樣的情況下,為了能夠在jsp中區別到底引用的是哪個標籤庫,可以換一種引用方式:<%@taglib uri="要引用的標籤庫的tld檔案目錄" prefix="gacl"%>,使用taglib指令引入標籤庫時,taglib指令的uri屬性指定為標籤庫的tld檔案目錄,這樣就可以區別開了,例如:

  引用gacl.tld標籤庫:<%@taglib uri="/WEB-INF/gacl.tld" prefix="gacl"%>、

  引用simpletag.tld標籤庫:<%@taglib uri="/WEB-INF/simpletag.tld" prefix="gacl"%>

  所以當在項目中引用了多個標籤庫,如果標籤庫的uri剛好是一樣的,就可以用這種方式解決。

六、簡單標籤開發步驟總結

  1、編寫一個類繼承SimpleTagSupport類,然後根據業務需要重寫SimpleTagSupport類中已經實現了的方法,一般情況下只需要重寫doTag()方法即可。

  2、在WEB-INF目錄下建立一個tld檔案,在tld檔案中添加對該標籤的描述。tld檔案不一定放在WEB-INF目錄下,也可以放在別的目錄,習慣是放在WEB-INF目錄下。

javaweb學習總結(二十五)——jsp簡單標籤開發(一)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.