jsp自定義標(biāo)簽用法實(shí)例詳解
本文實(shí)例講述了jsp自定義標(biāo)簽用法。分享給大家供大家參考。具體如下:
在JSP中有一種機(jī)制,可以讓你在JSP頁(yè)面中插入與HTML類似的標(biāo)記。本文介紹JSP定制標(biāo)記的基本概念和構(gòu)成,以及如何開(kāi)發(fā)和應(yīng)用JSP定制標(biāo)記。
什么是標(biāo)記
使用HTML語(yǔ)言我們可以這樣去編輯我們的網(wǎng)頁(yè):
<HTML> <HEAD> <TITLE> HELLO WORLD </TITLE> </HEAD> <BODY> HELLO WORLD </BODY> </HTML>
在這里我們把</HEAD>,<TITLE>,<BODY>稱為標(biāo)記。HTML 標(biāo)記( HTML Markup)是HTML文檔的控制語(yǔ)言,用于指定瀏覽器顯示和打印文檔的方式.它是用小于號(hào)"<"和大于號(hào)">"括起來(lái)的短語(yǔ)和符號(hào),如 <Html>、</Body>等。許多HTMl標(biāo)記以成對(duì)的方式出現(xiàn),如<TITLE>< /TITLE>、<Body></Body> 等。在JSP中我們也可以定制自己的標(biāo)記,以供JSP頁(yè)面使用,如下例所示
<!—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>就是一個(gè)JSP定制標(biāo)記符。widtht、height是這個(gè)標(biāo)記的屬性。<%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>是一個(gè)標(biāo)記庫(kù)定義指令,在稍后我們將會(huì)討論。在JSP中定制標(biāo)記符,實(shí)質(zhì)上就是以標(biāo)記的形式封裝了一個(gè)俱有獨(dú)立功能的Java類。標(biāo)記的使用減少了直接嵌入JSP頁(yè)面的Java代碼,方便了頁(yè)面的布局,并且有利于代碼的復(fù)用,提高了開(kāi)發(fā)的效率。
JSP服務(wù)器解析標(biāo)記的過(guò)程
那么當(dāng)一個(gè)標(biāo)記被嵌入JSP頁(yè)面后,JSP服務(wù)器是如何對(duì)這個(gè)標(biāo)記進(jìn)行解析的呢?各對(duì)象的含義如下所示:
Client: 表示客戶端。
JSP-Server:JSP服務(wù)器。
JSP-Page:JSP頁(yè)面。
TLD: 標(biāo)記庫(kù)描述文件,定義標(biāo)記和標(biāo)記的各種屬性和處理文件等。
TagClass 標(biāo)記處理程序
當(dāng)一個(gè)用戶訪問(wèn)一個(gè)JSP頁(yè)面時(shí),這個(gè)請(qǐng)求被發(fā)送到JSP服務(wù)器,JSP服務(wù)器會(huì)根據(jù)這個(gè)請(qǐng)求去調(diào)用相應(yīng)的頁(yè)面,如果這個(gè)頁(yè)面中有自定義的標(biāo)記, JSP服務(wù)就會(huì)根據(jù)頁(yè)面指令<%@ taglib>去訪問(wèn)TLD得到處理程序的相關(guān)信息,接著調(diào)用該處理程序的構(gòu)造器方法,啟動(dòng)標(biāo)記符處理程序,并讀取標(biāo)記符的屬性和相應(yīng)值。對(duì)每個(gè)沒(méi)有設(shè)置屬性的,調(diào)用相應(yīng)的set方法。當(dāng)標(biāo)記符第一次使用時(shí),它的任何屬性都不會(huì)做過(guò)設(shè)置,因此對(duì)每個(gè)屬性都調(diào)用set方法。屬性設(shè)置完以后,JSP服務(wù)器調(diào)用處理程序的doStartTag(),然后再調(diào)用doEndTag()方法。最后JSP服務(wù)器會(huì)繼續(xù)處理剩下的頁(yè)面,在頁(yè)面結(jié)尾調(diào)用release ()方法,清理占用的所有資源。
TLD文件
TLD(TLD:Tag Library Descriptor標(biāo)記庫(kù)描述符)文件,標(biāo)準(zhǔn)的XML格式的標(biāo)記定義文件,被用來(lái)存放標(biāo)記符的信息,下面就是一個(gè)典型的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> <!—此標(biāo)記說(shuō)明我們開(kāi)始描述一個(gè)標(biāo)記庫(kù)--> <tlibversion>1.0</tlibversion> <!—標(biāo)記庫(kù)的版本--> <jspversion>1.1</jspversion> <!—所使用的JSP的版本--> <shortname>tagclass</shortname> <!—缺省的名稱--> <tag> <name>login</name> <!—標(biāo)記的名稱--> <tagclass> tagclass.login.login <!—處理這個(gè)Tag的相應(yīng)的類的名稱--> </tagclass> <info> <!—對(duì)本標(biāo)記符的描述--> </info> <attribute> <!—開(kāi)始定義標(biāo)記的屬性--> <name>height</name> <!—屬性的名稱--> <required>true</required> <!—表示這個(gè)屬性是不是必須的--> <rtexprvalue>true</rtexprvalue> <!—表示這個(gè)屬性是否可以用JSP的程序段的結(jié)果輸出--> </attribute> <attribute> <name>width</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
在這個(gè)TLD文件中定義了只有一個(gè)標(biāo)記符的標(biāo)記符庫(kù),這個(gè)名為login的標(biāo)記符會(huì)調(diào)用一個(gè)Applet以驗(yàn)證用戶的合法性。處理這個(gè)標(biāo)記的類就是 tagclass.login.login。width、height是這個(gè)標(biāo)記的兩個(gè)屬性。屬性是在使用標(biāo)記符時(shí)作為參數(shù)發(fā)送的值。我們可以在上面的示例中增加幾個(gè)標(biāo)記,也可以為每個(gè)標(biāo)記添加幾個(gè)屬性。我們開(kāi)發(fā)標(biāo)記符庫(kù)時(shí)不一定非要從頭開(kāi)始,自己編寫(xiě)一個(gè)全新TLD。我們可以使用某個(gè)集成的開(kāi)發(fā)的環(huán)境,也可以修改上面的例子。
TagLib指令
那么當(dāng)JSP服務(wù)器在解析一個(gè)標(biāo)記符時(shí),它是如何定義一個(gè)標(biāo)記庫(kù)的呢?這就是TagLib指令的主要責(zé)任。
Taglib 指令
定義一個(gè)標(biāo)記庫(kù)以及其自定義標(biāo)記的前綴.
JSP 語(yǔ)法
例子
<%@ 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文件使用了自定義的標(biāo)記,同時(shí)引用標(biāo)記庫(kù),
也指定了他們的標(biāo)記的前綴。 你必須在使用自定義標(biāo)記之前使用<% @ taglib %>指令。
屬性
uri="URIToTagLibrary" :Uniform Resource Identifier (URI)根據(jù)標(biāo)記的前綴對(duì)自定義的標(biāo)記進(jìn)行唯一的命名,URI可以是一個(gè)相對(duì)或絕對(duì)的路徑。
prefix="tagPrefix":在自定義標(biāo)記之前的前綴。如上例中的</tagclass:login>
標(biāo)記符的處理程序(Tag handle)
我們還是以一個(gè)例子來(lái)看下如何實(shí)現(xiàn)一個(gè)Tag handle。首先是看一下它的類圖:
讓我們?cè)倏匆幌滤拇a:
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; }
從以上我們可以看出,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的標(biāo)記符處理程序有幾個(gè)要求:①增加一個(gè)類,使之繼承 java.Servlet.jsp.tagext.TagSupport類。這個(gè)類提供了java.Servlet.jsp.tagext.Tag接口所要求的所有的方法。另外,還需要使用一些基本的API,使JSP容器能夠調(diào)用我們自己提供的標(biāo)記符處理程序。②必須為每個(gè)標(biāo)記符屬性分別創(chuàng)建一個(gè) get<attribute>和set<attribute>方法,JSP容器需要使用這些方法處理程序傳遞參數(shù)。③要為標(biāo)記符處理程序創(chuàng)建一個(gè)構(gòu)造器和自毀器。JSP需要使用構(gòu)造器啟動(dòng)處理程序。自毀器是在realease()方法中定義的。在處理程序的生命周期結(jié)束時(shí),需要調(diào)用自毀器釋放所占用的資源。④創(chuàng)建兩個(gè)名為doStartTag()和doEndTag()的方法,執(zhí)行具體的處理和輸出動(dòng)作。這兩個(gè)方法是在處理自定義標(biāo)記符的起始位置和結(jié)束位置調(diào)用的。它們的返回值是在Tag Interface里定義的靜態(tài)int,這幾個(gè)靜態(tài)值分別是:
SKIP_BODY隱含0 :跳過(guò)了開(kāi)始和結(jié)束標(biāo)簽之間的代碼。
EVAL_BODY_INCLUDE隱含1:將body的內(nèi)容輸出到存在的輸出流中
SKIP_PAGE隱含5 : 忽略剩下的頁(yè)面。
EVAL_PAGE隱含6:繼續(xù)執(zhí)行下面的頁(yè)
當(dāng)然標(biāo)記符也有它自己的缺點(diǎn)。很不方便的封裝過(guò)程,有限的功能。對(duì)于一些不太復(fù)雜和功能單一的邏輯描述,需要傳遞的參數(shù)要求不高時(shí),使用JSP標(biāo)記,要方便的多。對(duì)于大多數(shù)的商業(yè)邏輯應(yīng)用,還是使用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>
標(biāo)記符描述庫(kù):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>
標(biāo)記符處理程序: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; }
標(biāo)記符處理程序中所使用的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) { } }
希望本文所述對(duì)大家的JSP程序設(shè)計(jì)有所幫助。
- JSP自定義標(biāo)簽Taglib實(shí)現(xiàn)過(guò)程重點(diǎn)總結(jié)
- jsp struts1 標(biāo)簽實(shí)例詳解
- jsp頁(yè)面中如何將時(shí)間戳字符串格式化為時(shí)間標(biāo)簽
- JSP自定義標(biāo)簽rtexprvalue屬性用法實(shí)例分析
- JSP頁(yè)面中如何用select標(biāo)簽實(shí)現(xiàn)級(jí)聯(lián)
- JSP自定義分頁(yè)標(biāo)簽TAG全過(guò)程
- JSP中常用的JSTL fmt(format格式化)標(biāo)簽用法整理
- Jsp自定義標(biāo)簽和方法詳解
相關(guān)文章
jsp頁(yè)面數(shù)據(jù)分頁(yè)模仿百度分頁(yè)效果(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇jsp頁(yè)面數(shù)據(jù)分頁(yè)模仿百度分頁(yè)效果(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07一個(gè)開(kāi)發(fā)人員眼中的JSP技術(shù)(下)
一個(gè)開(kāi)發(fā)人員眼中的JSP技術(shù)(下)...2006-10-10通過(guò)過(guò)濾器(Filter)解決JSP的Post和Request中文亂碼問(wèn)題
這篇文章主要介紹了jsp中通過(guò)過(guò)濾器(Filter)解決JSP的Post和Request中文亂碼問(wèn)題的方法,需要的朋友可以參考下2014-08-08ajax+jsp草稿自動(dòng)保存的實(shí)現(xiàn)代碼
ajax+jsp草稿自動(dòng)保存的實(shí)現(xiàn)代碼...2007-05-05