在上一篇文章中介紹了自定義標簽的用法,接下來介紹標簽文件的用法啦。 tag file指令 tag file簡介 用tag file的方式,無需編寫標簽處理類和標簽庫描述文件,也可以自定義標簽。tag file從兩個方面簡化了自定義標簽的開發。首先,tag file無須提前編譯,直到第一次調用才會編譯 ...
在上一篇文章中介紹了自定義標簽的用法,接下來介紹標簽文件的用法啦。
tag file指令
tag file簡介
用tag file的方式,無需編寫標簽處理類和標簽庫描述文件,也可以自定義標簽。tag file從兩個方面簡化了自定義標簽的開發。首先,tag file無須提前編譯,直到第一次調用才會編譯;其次,標簽庫描述文件也不再需要了,使用tag file的方式,tag file名和action相同,因此不需要標簽庫描述文件了。
一個tag file和JSP頁面一樣,它擁有指令、腳本、EL表達式、動作元素以及自定義的標簽。一個tag file以tag和tagx為尾碼,它們可以包含其他資源文件。一個被其他文件包含的tag file應該以tagf為尾碼。
tag文件必須放在應用路徑的WEB-INF/tags目錄下才能生效。和標簽處理類一樣,tag文件可以被打包到jar包里。
以下是tag file中可用的隱藏對象(其實跟文章JSP隱藏對象類似):
對象 |
類型 |
說明 |
request |
javax.servlet.http.HttpServletRequest |
每當客戶端請求一個JSP頁面時,JSP引擎就會製造一個新的reuqest對象來代表這個請求。request對象提供了一系列方法來獲取HTTP頭信息、cookies、HTTP方法等等。 |
response |
javax.servlet.http.HtpServletResponse |
當伺服器創建request對象時會同時創建用於響應這個客戶端的response對象。response對象也定義了處理HTTP頭模塊的介面。通過這個對象,開發者們可以添加新的cookies、時間戳、HTTP狀態碼等等。 |
out |
javax.servlet.jsp.JspWriter |
out對象用來在response對象中寫入內容。 |
session |
javax.servlet.http.HttpSession |
session對象用來跟蹤在各個客戶端請求間的會話。 |
application |
javax.servlet.ServletContext |
application對象在JSP頁面的整個生命周期中都代表著這個JSP頁面。這個對象在JSP頁面初始化時被創建,隨著jspDestory()的調用而被移除。通過向application中添加屬性,則所有組成web應用的JSP文件都能訪問到這些屬性。 |
config |
javax.servelt.ServletConfig |
config對象允許開發者訪問Servlet或者JSP引擎的初始化參數,比如文件路徑等。 |
pageContext |
javax.servlet.jsp.PageContext |
pageContext對象主要用來訪問頁面信息,同時過濾大部分實現細節。該對象除了pageContext、page、exception對象的屬性不能導出,其餘內置對象的屬性都能導出,而且該對象包含了傳給JSP頁面的指令信息,也定義了一些欄位。 |
page |
javax.servlet.jsp.HttpJspPage |
page對象就是頁面實例的引用,可以被看做是整個JSP頁面的代表(與this對象同義) |
exception |
java.lang.Throwable |
exception對象包裝了從先前頁面中拋出的異常信息,通常被用來產生對出錯條件的適當響應。 |
接下來是創建一個標簽文件並且使用的例子:
創建標簽文件並使用只有兩步:
① 編寫標簽文件.tag(例如firstTag.tag),記住要在/WEB-INF/tags中創建此文件哦。
<%@ tag import="java.util.Date" import="java.text.SimpleDateFormat" import="java.io.IOException"%> <% SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = simpleDateFormat.format(new Date()); JspWriter jspWriter = getJspContext().getOut(); jspWriter.write(dateStr); %>
② 編寫jsp測試頁面。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> Today is <easy:firstTag/> </body> </html>
出來的頁面效果就跟自定義標簽展現出來的樣子是類似的哦。
tag file指令
tag file的指令不多,也就那麼幾個:
指令 |
說明 |
tag |
作用與JSP頁面中的page指令類似 |
include |
用於將其他資源導入tag file中 |
taglib |
用於將自定義標簽庫導入tag file中 |
attribute |
用於將自定義標簽庫導入tag file中 |
variable |
用於將自定義標簽庫導入tag file中 |
看著有點懵?沒事兒,接下來會挨個兒解釋。
① tag指令
語法:<%@ tag attribute="value" attribute2="value2" %>
屬性(除了import屬性,其他所有的屬性在一個tag指令或一個tag file中都只能出現一次。):
屬性 |
描述 |
display-name |
在XML工具中顯示的名稱。預設值是不包含尾碼的tag file名 |
body-content |
指定標簽body的類型, body-content屬性值有empty、tagdependent、scriptless,預設值是scriptless。 |
dynamic-attributes |
指定tag file動態屬性的名稱。當dynamicattributes值被設定時,會產生一個Map來存放這些動態屬性的名稱和對應的值。 |
small-icon |
指定一個圖片路徑,用於在XML工具上顯示小圖標。一般不會用到。 |
large-icon |
制定一個圖片路徑,用於在XML工具上顯示大圖標。一般不會用到。 |
description |
標簽的描述信息。 |
example |
標簽使用實例的描述。 |
language |
tag file中使用的腳本語言類型。當前版本的JSP中,該值必須設為”java”。 |
import |
用於導入一個java類型,和JSP頁面中的import相同。 |
pageEncoding |
指定tag file使用的編碼格式,可以使用“CHARSET”中的值。和JSP頁面中pageEncoding相同。 |
include指令
tag file中的include指令和JSP頁面中的include指令是一樣的。可以使用這個指令來將外部文件導入到tag file中。當你有一個公共資源文件有可能用在多一個tag file中時,include指令將能夠發揮它的作用。這個公共資源文件可以是靜態文件(如HTML文件),也可以是動態文件(如tag file)。
接下來是一個例子~(除了jsp頁面文件,其餘的文件都要放到tags文件夾中哦)。
① 創建一個tag file(如includeDemoTag.tag)。
Here is the content of included.html: <%@ include file="included.html" %> <br/> <br/> The second include directive includes another dynamic resource: included.tagf. <br/> <%@ include file="included.tagf" %>
② 創建一個.html文件(如included.html),用於展示實現include導入,html等靜態文件的功能。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <table> <tr><td><b>Menu</b></td></tr> <tr><td>CDs</td></tr> <tr><td>DVDs</td></tr> <tr><td>Others</td></tr> </table> </body> </html>
③ 創建一個.tagf文件(如included.tagf),用於展示實現include導入.tagf等動態文件的功能。
<% out.print("Hello from included.tagf"); %>
④ 創建一個.jsp頁面文件,用於測試include指令的作用。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <easy:includeDemoTag/> </body> </html>
出來的頁面效果是這樣子噠~
taglib指令
可以通過taglib指令在tag file中使用自定義標簽。
語法:<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>
屬性:uri屬性---用來指定與首碼相關聯的標簽庫描述文件的絕對路徑或相對路徑;prefix屬性---用來定義自定義標簽的首碼。
使用taglib指令,既可以使用不包含content body的自定義標簽:
<prefix:tagName/>
也可使用包含content-body的自定義標簽:
<prefix:tagName>body</prefix:tagName>
使用taglib指令的例子如下:
① 先創建一個.tag的文件(如taglibDemo.tag,此例中會用到上述的第一個例子中的firstTag.tag文件)
<%@ taglib prefix="simple" tagdir="/WEB-INF/tags"%> The server's date : <simple:firstTag/>
② 然後再創建一個.jsp(如taglibDemoTest.jsp)頁面文件,用來測試taglib指令。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <easy:taglibDemo/> </body> </html>
測試出來的效果是這樣的。
attribute指令
attribute用於設定tag file中標簽的屬性。它和標簽庫描述文件中的attribute元素等效。
語法:<%@ attribute attribute1="value1" attribute2="value2" %>
屬性(這些屬性中,只有name屬性是必選的):
屬性 |
描述 |
name |
用於設定該屬性的名稱,在一個tag file中,每個屬性的名稱必須是唯一的。 |
required |
用於設定該屬性是否是必須的。值可以去true或false,預設值為false。 |
fragment |
用於設定該屬性是否是fragment。預設值為false。 |
rtexprvalue |
用於設定該屬性的值是否在運行時被動態計算。值可以取true或false,預設值為true。 |
type |
用於設定該屬性的類型,預設值為java.lang.String。 |
description |
用於設定該屬性的描述信息。 |
以下是關於attribute指令的例子~
① 創建一個.tag文件(如encode.tag)
<%@ attribute name="input" required="true"%> <%! private String encodeHtmlTag(String tag){ if(tag==null){ return null; } int length = tag.length(); StringBuilder encodedTag = new StringBuilder(2*length); for(int i=0;i<length;i++){ char c = tag.charAt(i); if(c=='<'){ encodedTag.append("<"); }else if(c=='>'){ encodedTag.append(">"); }else if(c=='&'){ encodedTag.append("&"); }else if(c=='"'){ encodedTag.append("&qout"); }else if(c==' '){ encodedTag.append(" "); }else{ encodedTag.append(c); } } return encodedTag.toString(); } %> <%=encodeHtmlTag(input)%>
② 創建一個.jsp頁面進行測試(如encodeTagTest.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="easy" tagdir="/WEB-INF/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <easy:encode input="<br/> means changing line."/> </body> </html>
完成上述的步驟之後,得到的效果就是這樣的:
variable指令
tag file中的variable指令是用於定義那些需要傳遞到JSP頁面的變數。
tag file支持多個variable指令,這意味著可以傳遞多個值到JSP頁面。相對而言,attribute指令的作用與variable相反,它用於將值從JSP頁面傳遞到tag file。
語法:<%@ variable attribute1="value" attribute2="value2" %>
屬性:
屬性 |
描述 |
name-given |
變數名。在JSP頁面的腳本和EL表達式中,可以使用該變數名。如果指定了name-from-attribute屬性,那麼name-given屬性就不能出現了,反之亦然。name-given的值不能和同一個tag file中的屬性名重覆。 |
name-from-attribute |
和name-given屬性類似,由標簽屬性的值來決定變數的名稱。如果name-from-attribute和name-given屬性同時出現h或者都不出現的話會出現錯誤。 |
alias |
設定一個用來接收變數值的局部範圍。 |
variable-class |
變數的類型。預設為java.lang.String。 |
declare |
設定該變數是否聲明。預設值是false。 |
scope |
用於指定該變數的範圍。可取的值為AT_BEGIN、AT_END和NESTED。預設值為NESTED。 |
description |
用於描述變數。 |
以下是對variable指令的示例:
① 創建.tag文件(如varDemo.tag)
<%@ tag import="java.util.Date" import="java.text.DateFormat"%> <%@ variable name-given="longDate" %> <%@ variable name-given="shortDate"%> <% Date now = new Date(System.currentTimeMillis()); DateFormat longFormat = DateFormat.getDateInstance(DateFormat.LONG); DateFormat shortFormat = DateFormat.getDateInstance(DateFormat.SHORT); jspContext.setAttribute("longDate", longFormat.format(now)); jspContext.setAttribute("shortDate", shortFormat.format(now)); %> <jsp:doBody/>
② 創建一個用於測試的.jsp頁面(如varDemoTest.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> Today's date: <br/> <tags:varDemo> In long format:${longDate } <br/> In short format:${shortDate } <br/> </tags:varDemo> </body> </html>
通過以上的步驟得到的頁面效果就是下圖所示啦:
doBody
doBody動作元素只能在tag file中使用,它用來調用一個標簽的本體內容。doBody動作元素也可以有屬性。你可以通過這些屬性來指定某個變數來接收主體內容,如果不使用這些指令,那麼doBody動作元素會把主體內容寫到JSP頁面的JspWriter上。
doBody動作元素的屬性如下(這些屬性都是非必須的哦):
屬性 |
描述 |
var |
用於保存標簽主體內容的變數值,主體內容就會以java.lang.String的類型保存這個變數內。var和varReader屬性只能出現一個。 |
varReader |
用於保存標簽主體內容的變數值,主體內容就會以java.io.Reader的類型保存這個變數內。var和varReader屬性只能出現一個。 |
scope |
變數保存到的作用域。 |
接下來是doBody動作元素的例子:
① 創建一個.tag文件(如doBodyDemo.tag)。
<jsp:doBody var="referer" scope="session"></jsp:doBody> <!-- 意思是,一個doBody動作元素,指定了一個叫做referer的session屬性來保存標簽本體內容 -->
② 創建一個.jsp文件(如main.jsp),用於載入頭信息並且對referer變數的值進行賦值。
<%@ page language="java" contentType=