JSP自定義標簽和EL自定義函數(shù)開發(fā)
一、自定義標簽
1、自定義標簽好處:
1)可以降低 jsp 開發(fā)的復雜度和維護量。
2)從 html 角度來說,可以使 html 不用去過多的關(guān)注那些比較復雜的商業(yè)邏輯。
3)利用自定義標簽,可以軟件開發(fā)人員和頁面設計人員合理分工:頁面設計人員可以把精力集中在使用標簽 (HTML,XML或者JSP)創(chuàng)建網(wǎng)站上,而軟件開發(fā)人員則可以將精力集中在實現(xiàn)底層功能上面,如國際化等,從而提高了工程生產(chǎn)力。
4)將具有共用特性的 tag庫應用于不同的項目中,體現(xiàn)了軟件復用的思想。
2、什么是自定義標簽:
用 戶定義的一種自定義的jsp標記。當一個含有自定義標簽的jsp頁面被jsp引擎編譯成servlet時,tag標簽被轉(zhuǎn)化成了對一個稱為 標簽處理類的對象的操作。于是,當jsp頁面被jsp引擎轉(zhuǎn)化為servlet后,實際上tag標簽被轉(zhuǎn)化為了對tag處理類的操作.標簽庫 API: 標簽庫 API 定義在 javax.servlet.jsp.tagext 包中.
3、開發(fā)自定義標簽概述:
開發(fā)自定義標簽:其核心就是要編寫處理器類,一個標簽對應一個標簽處理器類,而一個標簽庫則是很多標簽處理器的集合。所有的標簽處理器類都要實現(xiàn) JspTag 接口,該接口中沒有定義任何方法,主要作為 Tag 和 SimpleTag 接口的父接口。在 JSP 2.0 以前,所有標簽處理器類都必須實現(xiàn) Tag 接口,這樣的標簽稱為傳統(tǒng)標簽。
JSP 2.0 規(guī)范又定義了一種新的類型的標簽,稱為簡單標簽,其對應的處理器類要實現(xiàn)SimpleTag 接口或處理類可以是對TagSupport類的擴展
4、標簽的形式:
空標簽:<hello/>
帶有屬性的空標簽:
<maxnum1=“3” num2=“5”/>
帶有內(nèi)容的標簽:
<greeting>
hello
</greeting>
帶有內(nèi)容和屬性的標簽:
<greetingname=“Tom”>
hello
</greeting>
5、自定義標簽的開發(fā)與應用步驟:
1). 編寫完成標簽功能的Java 類(標簽處理器)
2). 編寫標簽庫描述(tld)文件,在tld文件中對自定義中進行描述
3). 在 JSP 頁面中導入和使用自定義標簽
6、自定義標簽中的知識:
1)SimpleTag 接口介紹:
(1).setJspContext 方法:該方法把代表 JSP 頁面的pageContext 對象傳遞給標簽處理器對象。
(2). setParent 方法:該方法把父標簽處理器對象傳遞給當前標簽處理器對象
(3). getParent 方法:該方法用于獲得標簽的父標簽處理器對象
(4). setJspBody 方法:該方法用于把代表標簽體的 JspFragment 對象傳遞給標簽處理器對象
(5). doTag 方法:該方法用于完成所有的標簽邏輯。該方法可以拋出 javax.servlet.jsp.SkipPageException異常,用于通知 web 容器不再執(zhí)行 JSP 頁面中位于結(jié)束標記后面的內(nèi)容。
2)實現(xiàn) SimpleTag 接口的標簽處理器類的生命周期:
(1).Jsp 引擎將代表 JSP 頁面的 pageContext 對象傳遞給標簽處理器對象
(2).Jsp 引擎將父標簽處理器對象傳遞給當前標簽處理器對象。只有存在父標簽 時,jsp 引擎才會調(diào)用該方法
(3).設置標簽屬性。只有定義屬性才調(diào)用該方法
(4). 若存在標簽體, JSP 引擎將把標簽體封裝成一個 JspFragment 對象,調(diào)用 setJspBody 方法將 JspFragment 對象傳遞給標簽處理器對象。若標簽體為空,這setJspBody 將不會被 JSP 引擎調(diào)用
(5).容器調(diào)用標簽處理器對象的 doTag 方法執(zhí) 行標簽邏輯
3)JspFragment 類
該類的實例對象代表 JSP 頁面中的一段符合 JSP 語法規(guī)范的 JSP 片段,這段JSP 片段不能包含 JSP 腳本元素(<% …%>).JSP 引擎在處理簡單標簽的標簽體時,會把標簽體內(nèi)容用一個 JspFragment 對象表示,并調(diào)用標簽處理器對象的 setJspBody 方法把JspFragment 對象傳遞給標簽處理器對象。得到代表標簽體的 JspFragment 對象后,標簽開發(fā)者和就可以在標簽處理器中根據(jù)需要調(diào)用 JspFragment 對象的方法,進而決定如何處理標簽體getJspContext 方法:該方法用于返回代表調(diào)用頁面的 JspContext 對象
Invoke 方法(java.io.Writer out):該方法用于執(zhí)行 JspFragment 對象所代表的 JSP 代碼片段。在 doTag() 方法中可以根據(jù)需要調(diào)用該方法。該方法的參數(shù) out 用于指定將 JspFragment 對象的執(zhí)行結(jié)果寫入到哪個輸出流對象中。若傳遞參數(shù) out 的值為 null,則將執(zhí)行結(jié)果寫入到 JspContext.geOut() 方法返回的輸出流對象中。若想在標簽處理器中修改標簽體內(nèi)容:需在調(diào)用 invoke 方法時指定一個可取出結(jié)果數(shù)據(jù)的輸出流對象(如:StringWriter),讓標簽體的執(zhí)行結(jié)果輸出到該輸出流中,然后從該輸出流對象中取出數(shù)據(jù)進行修 改后在輸出到目標設備。
4)SimpleTagSupport類介紹:
為簡化簡單標簽處理器的編寫工作,JSP API中提供了SimpleTag接口的一個實現(xiàn)SimpleTagSupport.
SimpleTagSupport實現(xiàn)了SimpleTag接口中的方法,它內(nèi)部以成員變量的形式保存了setJspContext方法和setJspBody方法傳遞進來的參數(shù)。此外,它還定義了如下兩個方法、來返回這兩個參數(shù):
A. getJspContext方法:該方法用于返回代表調(diào)用頁面的JspContext對象
B. getJspBody方法:該方法用于得到代表標簽體的JspFragment對象
7、標簽庫描述文件介紹:
標簽庫描述(Tag LibraryDescription)文件簡稱為 tld 文件,其擴展名為.tld多個標簽的集合就形成了一個標簽庫,標簽庫中的所有標簽都必須在標簽文件中進行描述Tld 文件可以放置在 web 應用程序的 WEB-INF 目錄及其子目錄中,但不能放置在 WEB-INF 目錄下的 classes 和 lib 子目錄中 。
tld 文件也可以放置在 WEB-INF\lib 目錄下的 jar 包的 META-INF 目錄及其子目錄中。
1)、標簽庫描述文件,簡稱TLD,采用XML文件格式,定義了用戶的標簽庫。TLD文件中的元素可以分成三類:
A.標簽庫元素
B.標簽元素
C.標簽屬性元素
2)、標簽庫元素用來設定標簽庫的相關(guān)信息,它的常用屬性有:
A.tlib-version:指定標簽庫實現(xiàn)版本信息
B.shortname:指定Tag Library默認的前綴名(prefix);
C.uri:設定Tag Library的惟一訪問表示符。
3)、標簽元素用來定義一個標簽,它的常見屬性有:
A.name:設定Tag的名字;
B.tagclass:設定Tag的處理類;
C.bodycontent:設定標簽的主體(body)內(nèi)容:
a、empty:表示標簽中沒有body;
b、tagdependent:表示標簽中的內(nèi)容由標簽自己去處理;
c、JSP:表示標簽的body中可以加入JSP程序代碼;
d、scriptless:指定標簽的標簽體可以是靜態(tài)HTML、表達式語言,但不允許出現(xiàn)JSP腳本。
4、標簽屬性元素用來定義標簽的屬性,它的常見屬性有:
A.name:屬性名稱;
B.required:屬性是否必需的,默認為false;
C.fragment:屬性值是否可以為支持JSP腳本、表達式等動態(tài)內(nèi)容。
<body-content>:指定標簽體的類型??赡苋≈涤?3 種:
empty:沒有標簽體
scriptless:標簽體可以包含 el 表達式和 JSP 動作元素,但不能包含 JSP 的腳本元素
tagdependent:表示標簽體交由標簽本身去解析處理。若指定tagdependent,在標簽體中的所有代碼都會原封不動的交給標簽處理器,而不是將執(zhí)行結(jié)果傳遞給標簽處理器
8、在 JSP 頁面引用自定義標簽:
在標準 JSP 頁面中使用taglib 指令來引入 tld 文件:
<%@ tagliburi="/petrelskyTag" prefix="petrelsky"%>
uri:屬性用于指定所引入的標簽庫描述(tld)文件中所定義的 <uri> 元素的內(nèi)容;
prefix 屬性用于為引入的 tld 文件指定一個”引用名” ,作者任意指定,只要與其他taglib 指令的 prefix 屬性值不同就可以。
二、EL 自定義函數(shù)開發(fā)步驟:
1. 編寫 EL 自定義函數(shù)映射的Java類中的靜態(tài)方法: 這個 Java 類必須帶有 public 修飾符,方法必須是這個類的帶有 public 修飾符的靜態(tài)方法
2. 編寫標簽庫描述文件(tld 文件), 在 tld 文件中描述自定義函數(shù)
3. 在 JSP 頁面中導入和使用自定義函數(shù)
4.EL自定義函數(shù)使用:
EL 自定義函數(shù),在標準 JSP 頁面中使用 taglib 指令來引入 tld 文件:
<%@ tagliburi="/petrelskyTag" prefix="petrelsky"%>
uri:屬性用于指定所引入的標簽庫描述(tld)文件中所定義的 <uri> 元素的內(nèi)容;
prefix 屬性用于為引入的 tld 文件指定一個”引用名” ,作者任意指定,只要與其他taglib 指令的 prefix 屬性值不同就可以。
調(diào)用 EL 自定義函數(shù): ${petrelsky:toGBK (param.username) }
三、 例子:
1.JSP標簽
示例1
1),寫JAVA類標簽處理器
package cn.itcast.simpleTag;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;
public class ParamTag implements SimpleTag {
private PageContext pageContext = null;
public void doTag() throws JspException, IOException {
System.out.println("hello doTag....");
HttpServletRequest request = null;
JspWriter out = null;
request = (HttpServletRequest) pageContext.getRequest();
out = pageContext.getOut();
String name = request.getParameter("name");
out.print("Hello: " + name);
}
public JspTag getParent() {
return null;
}
public void setJspBody(JspFragment arg0) {
}
public void setJspContext(JspContext arg0) {
this.pageContext = (PageContext) arg0;
}
public void setParent(JspTag arg0) {
}
}
2)寫TLD 文件
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<description>myTag 1.1 core library</description>
<display-name>myTag core</display-name>
<tlib-version>1.0</tlib-version>
<short-name>itcast</short-name>
<uri>http://itcast.cn/jsp/mytag</uri>
<tag>
<name>param</name>
<tag-class>cn.itcast.simpleTag.ParamTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
3)寫JSP 頁面 :
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/tld/mytag_1_ex.tld" prefix="itcast" %>
<html>
<head><title>My JSP 'test.jsp' starting page</title></head>
<body>
<itcast:param/>
</body>
</html>
由上面可以看出,所謂標簽就是用在視圖層,JSP頁面中根本看不到JAVA 的程序,而是JAVA 程序?qū)懥藗€標簽,然后在JSP 頁面中使用,頁面看起來十分簡潔!這個就是自定義標簽的強大之處!前提是以JAVA為基礎的!
示例2
package cn.itcast.simpleTag.ex;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;
public class ToLowerCaseTag implements SimpleTag {
private PageContext pageContext;
private JspFragment bodyContent;
public void doTag() throws JspException, IOException {
// TODO Auto-generated method stub
//1. 得到標簽體的文本
StringWriter sw = new StringWriter();
bodyContent.invoke(sw);
String bodyContentString = sw.toString();
//2. 把標簽體文本變成小寫
bodyContentString = bodyContentString.toLowerCase();
//3. 輸出
pageContext.getOut().print(bodyContentString);
}
public JspTag getParent() {
// TODO Auto-generated method stub
return null;
}
public void setJspBody(JspFragment arg0) {
// TODO Auto-generated method stub
this.bodyContent = arg0;
}
public void setJspContext(JspContext arg0) {
// TODO Auto-generated method stub
this.pageContext = (PageContext) arg0;
}
public void setParent(JspTag arg0) {
// TODO Auto-generated method stub
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<description>mytag</description>
<display-name>mytagcore</display-name>
<tlib-version>1.2</tlib-version>
<short-name>itcast</short-name>
<uri>http://itcast.cn/mytag_ex</uri>
<tag>
<name>toLowerCase</name>
<tag-class>cn.itcast.simpleTag.ToLowerCaseTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/tld/mytag.tld" prefix="itcast" %>
<html>
<head><title>My JSP 'test.jsp' starting page</title></head>
<body>
<itcast:toLowerCase>
HELLO ITCAST.CN.
</itcast:toLowerCase>
</body>
</html>
2、EL自定義函數(shù)例子:
示例1
1)自定義El函數(shù)庫
public class FunctionsEl {
publicstatic String decode(String str) throws UnsupportedEncodingException{
if(StringUtils.isNotBlank(str)){
returnURLDecoder.decode(str,"utf-8");
}
return"";
}
}
2)寫一個tld文件
<?xml version="1.0"encoding="UTF-8" ?>
<taglibxmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>MYJSTL 1.0 functions library</description>
<display-name>MYJSTL functions</display-name>
<tlib-version>1.0</tlib-version>
<short-name>myfn</short-name>
<uri>http://www.xxx.cn/jsp/jstl/functions</uri>
<function>
<name>decode</name>
<!--此處是定義類的路徑-->
<function-class>cn.xxx.crm.functions.FunctionsEl</function-class>
<!--此處是定義類的返回值類型和傳入?yún)?shù)類型-->
<function-signature>java.lang.String decode(java.lang.String)</function-signature>
</function>
</taglib>
3)在jsp頁面中的使用:
<%@ tagliburi="http://www.xxx.cn/jsp/jstl/functions" prefix="myfn"%>
${myfn:decode(string)}
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。