Tag檔案和Tag標記的用法詳解
Tag檔案和Tag標記
目錄
1.為什麼要使用Tag檔案
1) 在Web應用中許多JSP頁面都有相同的資訊,如都需要相同的導航欄和尾頁等。如果能把相同的資訊都形成一種特殊的檔案,而且各個JSP頁面都可以使用這種特殊的檔案,那麼就能實現程式碼的複用,維護性就比較好了
2)實現程式碼複用還有另外兩種方式,include指令和include動作,那就來說說他們的不足吧,首先不論是include指令還是include動作處理的都是單一 的JSP檔案,使用者可以通過輸入位址列的方式來訪問響應的JSP檔案,這時候使用者訪問的JSP檔案可能只是一個導航欄,這不是設計者希望看到的.include指令的耦合性太大,include動作雖然耦合性較小但是能放在Web服務目錄的任意子目錄中,不僅顯的雜亂無章,還不利於管理和維護.
3)使用tag檔案就能很好的解決這一缺點,tag檔案不僅能實現動態載入實現程式碼複用,還不能讓使用者直接訪問,tag檔案放在指定 的目錄下,維護起來會比較方便(很多時候會讓tag檔案去處理資料,而JSP頁面只是去顯示資料,實現資料顯示和資料處理分離,這樣就比較便於維護了)
2.Tag檔案的結構
Tag檔案是副檔名為.tag的檔案,其實與JSP檔案差不多.在Tag檔案中可以使用HTML標籤,可以使用java指令碼以及JSP動作和指令,還可以使用某些特殊的指令(後面會講)
3.Tag檔案的儲存目錄
Tag檔案必須存在/WEB-INF/tags 資料夾下(不然會報錯),存放目錄如下圖所示:
4.Tag標記
編寫了一個Tag檔案會對應生成一個Tag標記,Tag標記的格式為:
<Tag 檔名字/>或
<Tag 檔名字>
標記體
</Tag 檔名字>
當JSP頁面希望向Tag檔案傳遞相應的資訊時,可以使用標記體來傳遞,在Tag檔案中通過<jsp:doBody/>來呼叫標記體
一個Tag檔案對應一個Tag標記,那麼該目錄下有若干個Tag檔案就行成了一個庫,在JSP頁面要呼叫Tag檔案,就要通過taglib指令來引入相應目錄下的一個標記庫,只有這樣JSP頁面才能呼叫相應的Tag檔案並動態執行該Tag檔案
<%@taglib prefix="字首" tagdir="自定義標記庫的位置"%>
注意:使用字首可以區別不同標記庫下相同名字的標記檔案
如:呼叫/WEB-INF/tags/math/random.tag檔案就可以在JSP頁面中這樣寫
<%@taglib prefix="math" tagdir="/WEB-INF/tags/math/"%>來引入標記庫
之後可以<math:random/>或者<math:random>標記體</math:random>來呼叫了並執行相應tag檔案了
5.Tag檔案中常用的指令
1)tag指令
1.body-content屬性
body-content屬性的值有empty、tagdependent、scriptless,其預設值是scriptless
empty:當body-content屬性的屬性值為empty時,JSP頁面中必須使用沒有標記體的tag標記,<Tag 檔名字>
tagdependent:當body-content屬性的屬性值為tagdepentdent時,JSP頁面通過標記體傳來的資訊全部按純文字處理
scriptless:當body-content屬性的屬性值為scriptless時,標記體中不能使用Java程式塊,可以使用文字,EL表示式,一個自定義標記,一個動作
2.language屬性
其屬性值只支援java
3.import屬性
引入java核心類包,可以在Tag檔案中使用某些類,跟導包沒什麼區別就不說了
4.pageEncoding屬性
Tag檔案的編碼屬性,其預設值是ISO-8859-1
2)attribute指令
Tag檔案充當著程式碼複用的角色,如果能像include動作一樣向Tag檔案傳遞資料,這會讓Tag檔案的功能更加強大,這當然是可以的,在Tag檔案中有attribute指令,其語法格式如下:
<%attribute name="物件名字" required="true"|"false" type="物件的型別"%>
attribute指令中name屬性是必須的,該屬性是引用一個物件的名字.required為true時必須給其傳值,為false時可以傳可以不傳,type為該物件的型別,預設為java.lang.String型別,可以改為其他型別,但要注意的是,必須物件型別必須帶有包名,如不能簡寫為type="Integer"必須是type="java.lang.Integer"
需要注意的是:在Tag檔案中不可以再定義和attribute指令中name屬性指定的物件具有相同名字的變數,否則將隱藏attribute指令中的物件,使其失效(可以通過觀察原始碼發現,attribute中的變數其實在Tag檔案中一個成員變數)
下面是使用attribute指令的一個例子計算三角形面積的例子:
JSP頁面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="kai" tagdir="/WEB-INF/tags/geng" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'MyJsp.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="" method="post"> 邊長A: <input type="text" value="" name="a"><br> 邊長B: <input type="text" value="" name="b"><br> 邊長C: <input type="text" value="" name="c"><br> <input type="submit" value="Enter"> </form> <br> <% if((request.getParameter("a")!=null && request.getParameter("a")!="") && (request.getParameter("b")!=null && request.getParameter("b")!="") && (request.getParameter("c")!=null && request.getParameter("c")!="") ){ %> <kai:Addsum a="<%=Double.valueOf(request.getParameter(\"a\"))%>" b="<%=Double.valueOf(request.getParameter(\"b\"))%>" c="<%=Double.valueOf(request.getParameter(\"c\"))%>"> </kai:Addsum> <%}%> </body> </html>
tag檔案:
<%@tag import="java.text.DecimalFormat"%> <%@tag pageEncoding="UTF-8" body-content="scriptless"%> <%@attribute name="a" required="false" type="java.lang.Double"%> <%@attribute name="b" required="false" type="java.lang.Double"%> <%@attribute name="c" required="false" type="java.lang.Double"%> <html> <head> </head> <body> 以下是呼叫Tag檔案的效果:<br> 這是一個Tag檔案,負責計算三角形的面積.<br> JSP頁面傳遞過來的三條邊:<%=a%>,<%=b%>,<%=c%><br> <% DecimalFormat format = new DecimalFormat("0.00"); if(a+b>c && a+c>b && b+c>a){ double p = (a+b+c)/2; out.print("三角形的面積: "+format.format(Math.sqrt(p*(p-a)*(p-b)*(p-c)))); }else{ out.print("<br>"+a+" "+b+" "+c+" 不能構成三邊"); } %> </body> </html>
3)variable指令
Tag檔案通過使用attribute指令JSP頁面可以向Tag檔案傳遞資料.在某些Web設計中,不僅需要向其傳遞資料,還需要他返回某些資料進行特殊處理.比如多個JSP頁面需要Tag檔案處理一些資料,但是不需要顯示,因為每個JSP頁面需要特殊的顯示,這時候就可以使用variable指令,variable指令語法格式如下:
<%variable name-given="物件名字" variable-class="物件型別" scope="有效範圍"%>
name-given:用來指定物件的名字,要符合命名規則
variable-class:指定的型別,注意需要打全包名,不能進行簡寫
scope中有三個屬性值:
1.AT_BEGIN,在使用JSP頁面標記的時候就可以使用該物件
2.NESTED,只能在標記體中使用該物件
3.AT_END,只能在標記體結束後使用該物件
Tag通過jspContext.setAttribute("物件的名字",物件的引用);把物件名字和物件引用儲存到內建物件jspContext中,JSP頁面才能使用該物件
4)taglib指令
和JSP頁面一樣,Tag檔案中也可以使用taglib指令來呼叫其他的tag檔案,操作一樣
5)include指令
其用法與JSP頁面中的include指令差不多,這裡就不說了
6.Tag檔案的巢狀
在使用Tag標記時,可以帶有標記體,標記體還可以是一個Tag標記,這就實現了Tag標記的巢狀