JSP自訂標籤(1)__JSP

來源:互聯網
上載者:User

一、引入標籤

其實在JSP中我們已經使用過了幾個標籤,比如<jsp:forward>、<jsp:include>等;這些標籤都是預先定義好的,如果我們需要自訂標籤,就需要學習標籤編程。

標籤編程的優點就是靈活性+封裝性。

靈活性體現在屬性的賦值上,可以賦任意值。比如<jsp:forward page="A">   //A處可以賦任意的URL;

封裝性體現在內部的行為的封裝,因為標籤是用一個類實現的,因此類的方法中能夠包含任意複雜的動作。

因此標籤是為了能夠在JSP中使用儘可能少的Scriptlet;

比如:

 <table> <% for(int i=0;i<10;i++){ %> <tr> <%  for(int j=0;j<10;j++){ %>  <td><%=i*j%></td> <%  } %>  </tr> <% } %> </table>

這個代碼非常混亂,但是如果通過標籤,從這段代碼都封裝在一個標籤裡,則代碼就清晰了很多。


接下來是我通過標籤封裝後的JSP頁面效果;

<%@ page contentType="text/html" pageEncoding="GBK"%><%@ taglib prefix="xiazdong" uri="xiazdong"%><html><head><title></title></head><body><xiazdong:table row="5" col="3"/></body></html>

是不是大大縮短了呢??再來看看我在背後幹了什麼。。。。

TableTagSupport.java

package org.tagext;import javax.servlet.jsp.tagext.*;import javax.servlet.jsp.*;public class TableTagSupport extends TagSupport{private String row;private String col;public String getRow(){return row;}public String getCol(){return col;}public void setRow(String row){this.row = row;}public void setCol(String col){this.col = col;}public int doStartTag()throws JspException{JspWriter out = super.pageContext.getOut();try{out.println("<table border=\"3\"> ");for(int i=0;i<Integer.parseInt(row);i++){out.println("<tr>");for(int j=0;j<Integer.parseInt(col);j++){out.println("<td>"+i*j+"</td>");}out.println("</tr>");}out.println("</table>");}catch(Exception e){}return TagSupport.SKIP_BODY;}}

是不是很神奇。。。那接下來就看看實現的過程吧。

注意,在編寫標籤之前,必須把tomcat\lib中的jsp-api.jar檔案配置在CLASSPATH中才可以;


二、基本標籤編寫
1、TagSupport類

如果要編寫一個標籤類,則必須繼承javax.servlet.jsp.tagext.TagSupport

TagSupport中提供了很多常用方法:

(1)    public int doStartTag()throws JspException;    //    標籤開始時調用

能夠返回SKIP_BODY(跳過標籤體)、EVAL_BODY_INCLUDE(執列標籤體)

(2)    public int doEndTag()throws JspException;    //     標籤結束時調用

能夠返回SKIP_PAGE(立刻停止執行)、EVAL_PAGE(JSP正常運行完畢);

(3)    int SKIP_BODY;        // 跳過標籤體

(4)    int EVAL_BODY_INCLUDE;    //執列標籤體

(5)    int EVAL_BODY_AGAIN;    //  重複執列標籤體,主要是因為集合迭代輸出,只能在doAfterBody中使用;

(6)    public int doAfterBody()throws JspException;    //   執行完一次標籤體後調用的函數;

能夠返回SKIP_BODY(結束標籤體)、EVAL_BODY_AGAIN(重複執列標籤體)

(7)  JspWriter out = super.pageContext.getOut();//擷取向網頁輸出的輸出資料流;

舉例講述這些函數和常量代表什麼意思:

<xiazdong:hello>                                <!--標籤頭 -->        <h3><%="xiazdong"%></h3>            <!--    標籤體--></xiazdong:hello>                                <!-- 標籤尾-->

執行流程如下:

(1)doStartTag();   <xiazdong:hello>時調用,如果是EVAL_BODY_INCLUDE,則繼續;如果是SKIP_BODY,則執行(4)

(2)執列標籤體;

(3)如果實現了doAfterBody,則執行;如果返回SKIP_BODY,則執行(4) ; 如果返回EVAL_BODY_AGAIN,則重複執行doAfterBody;

(4)doEndTag():標籤尾調用;
 2.製作無屬性標籤


為了清晰,我們以例子說明。

代碼舉例1:實現顯示Hello world;


1.編寫HelloTag.java


package org.tagext;import javax.servlet.jsp.tagext.*;import javax.servlet.jsp.*;public class HelloTag extends TagSupport{public int doStartTag()throws JspException{JspWriter out = super.pageContext.getOut();try{out.println("<h3>Hello world!!!</h3>");}catch(Exception e){}return TagSupport.SKIP_BODY;}}

注意點:

(1)javax.servlet.jsp.tagext.TagSupport,必須記住;

(2)JspWriter out = super.pageContext.getOut();

(3)public int doStartTag()throws JspException;必須記住;


2.編寫xiazdong.tld 


tld檔案是標籤描述檔案,是整個標籤編程的核心,用來描述自訂的標籤的名字、標籤的實作類別、是否有標籤體、描述屬性等;

一個tld檔案其實類似於一個標籤庫,裡面能夠描述很多標籤;每個標籤都以

<tag><name>hello</name><!--表示標籤的名字 類似於<jsp:forward>中的forward--><tag-class>org.tagext.HelloTag</tag-class><!--標籤所在類 --><body-content>empty</body-content><!--是否存在標籤體--></tag>

的形式描述;

*.tld檔案的模版如下:(因為tld檔案前面這些內容都不是很重要,因此可以直接複製黏貼)

<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/j2ee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"    version="2.0"><tlib-version>1.0</tlib-version>//插入tag描述</taglib>


3.在web.xml中編寫映射


編寫映射的目的類似於給一個網頁配置一個映射地址,為了方便訪問;

比如本來需要訪問/a/b/c/d/e/f/g/1.tld,這個路徑非常麻煩,但是如果通過映射,我們可以只需要用"a"表示一長串的檔案路徑及名稱;

<jsp-config><taglib><taglib-uri>xiazdong</taglib-uri><taglib-location>/WEB-INF/classes/xiazdong.tld</taglib-location></taglib></jsp-config>


4.編寫JSP頁面並使用自訂的標籤


<%@ taglib prefix=""   uri=""%>        prefix類似於<jsp:forward>中的jsp,uri中使用前面所說的映射;

<%@ page contentType="text/html" pageEncoding="GBK"%><%@ taglib prefix="xiazdong" uri="xiazdong"%><html><head><title></title></head><body><h1><xiazdong:hello/></h1></body></html>


 3.製作有屬性標籤

其實製作有屬性和製作無屬性沒有太大區別,


1.需要在原來的HelloTag.java 中加入屬性.

如果做形如:<xiazdong:hello id="" format="" />的屬性,則需要在HelloTag.java中添加兩個屬性,id屬性和format屬性;

形如:

class HelloTag extends TagSupport{private String id;private String format;//setter和getterpublic int doStartTag()throws JspException{}}

在使用者使用標籤,並為id和format屬性賦值時,會自動調用setter方法,將HelloTag類中的id和format賦值;


2.在tld檔案中添加屬性描述:

屬性描述形如:

<body-content>empty</body-content>後面加上<attribute><name>name</name><!--屬性姓名 --><required>true</required><!--屬性是否必要 --><rtexprvalue>empty</rtexprvalue><!--是否支援運算式語言 --></attribute>


代碼執行個體:


HelloTag.java

package org.tagext;import javax.servlet.jsp.tagext.*;import javax.servlet.jsp.*;public class HelloTag extends TagSupport{private String name;private String age;public String getName(){return name;}public String getAge(){return age;}public void setName(String name){this.name = name;}public void setAge(String age){this.age = age;}public int doStartTag()throws JspException{JspWriter out = super.pageContext.getOut();try{out.println("<h3>姓名:"+name+"</h3>");out.println("<h3>年齡:"+age+"</h3>");}catch(Exception e){}return TagSupport.SKIP_BODY;}}


xiazdong.tld 需要加上attribute的描述:名字、是否必須、是否支援運算式語言

<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/j2ee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"    version="2.0">  <tlib-version>1.0</tlib-version>  <short-name>x</short-name>  <tag><name>hello</name><tag-class>org.tagext.HelloTag</tag-class><body-content>empty</body-content><attribute><name>name</name><required>true</required><rtexprvalue>empty</rtexprvalue></attribute><attribute><name>age</name><required>true</required><rtexprvalue>empty</rtexprvalue></attribute>  </tag></taglib>

HelloTag.jsp

<%@ page contentType="text/html" pageEncoding="GBK"%><%@ taglib prefix="xiazdong" uri="xiazdong"%><html><head><title></title></head><body><h1><xiazdong:hello name="xiazdong" age="20"/></h1></body></html>

三、IterationTag和Tag介面的區別
Tag介面只有一些最基本的標籤編程方法,而IterationTag介面是用於迭代輸出,比如EVAL_BODY_AGAIN等;



相關文章

聯繫我們

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