① 從一個jsp頁面跳轉到另一jsp頁面,怎樣用jstl取得參數值
<c:url>標簽可以的
<c:urlvar="myURL"value="main.jsp">
<c:paramname="name"value="Runoob"/>
<c:paramname="sex"value="1"/>
</c:url>
② jsp中的JSTL與EL表達式用法及區別
JSTL (JSP Standard Tag Library ,JSP標准標簽庫)
JSTL標簽庫分為5類:JSTL核心標簽庫、函數標簽庫、資料庫標簽庫、I18N格式化標簽庫、XML標簽庫。
JSTL的核心標簽庫主要包括:表達式操作、流程式控制制、迭代操作和URL操作。以下是JSTL常用標簽的用法:
一、表達式操作
1、<c:out>
作用:用於顯示數據的內容。
語法1:沒有本體內容
<c:out value="value" [escapeXml="{true|false}"] [default="defaultValue"] />
語法2:有本體內容
<c:out value="value" [escapeXml="{true|false}"]>
default value
</c:out>
屬性說明:
value:需要顯示出來的值。
default:如果value的值為null時,則顯示default指定的值。
escapeXml:是否轉換特殊字元,默認為true。即默認會將<、>、』、」 和 & 轉換為 <、>、'、"和&。如果設為false,則不進行轉換。
2、<c:set>
作用:用於將變數的值存儲在JSP范圍中或javaBean的屬性中。
語法1:將value的值存儲在范圍為scope的varName變數中
<c:set value="value" var="varName" [scope="{page|request|session|application}"] />
語法2:將本體內容的數據存儲在范圍為scope的varName變數中
<c:set var="varName" [scope="{page|request|session|application}"] >
...本體內容
</c:set>
語法3:將value的值存儲在target對象的property屬性中
<c:set value="value" target="target" property="propertyName" />
語法4:將本體內容的數據存儲在target對象的property屬性中
<c:set target="target" property="propertyName">
...本體內容
</c:set>
屬性說明:
value:要被存儲的值。
var:欲存入的變數名稱。
scope:var變數的JSP范圍。默認為page范圍。
target:為一JavaBean或Map對象。
如果「target」是一個Map,「property」指定的是該Map的一個鍵;如果「target」是一個bean,「property」指定的 是該bean的一個成員欄位。
如果「target」表達式為null,容器會拋出一個異常。
如果「target」表達式不是一個Map或bean,容器會拋出一個異常。
如果「target」表達式是一個bean,但是這個bean沒有與「property」匹配的成員欄位,容器會拋出一個異常。
property:指定的target對象的屬性。
3、<c:remove>
作用:移除變數。
語法:<c:remove var="varName" [scope="{page|request|session|application}"] />
屬性說明:
var:要移除的變數。
scope:var變數所在的JSP范圍,默認為page范圍。
4、<c:catch>
作用:用於處理產生錯誤的異常情況,並將錯誤信息存儲起來。
語法: <c:catch [var="varName"] >
...欲抓取錯誤的部分
</c:catch>
屬性說明:
var:將錯誤信息存儲在指定的變數中,可以通過該變數獲取錯誤信息。
二、流程式控制制
1、<c:if>
作用:類似if判斷語句,用於表達式判斷。
語法1:沒有本體內容
<c:if test="testCondition" var="varName" [scope="{page|request|session|application}"] />
語法2:有本體內容
<c:if test="testCondition" [var="varName"] [scope="{page|request|session|application}"] />
...本體內容
</c:if>
屬性說明:
test:當該屬性中的表達式運算結果為true,則會執行本體內容,為false則不執行,該標簽必須要有test屬性。
var:存儲test的運算結果,為true或false。
scope:var變數的JSP范圍。
2、<c:choose>、<c:when>、<c:otherwise>
作用:這三個標簽必須組合使用,用於流程式控制制。
範例:
<c:choose>
<c:when test="${condition1}">
condition1為true
</c:when>
<c:when test="${ condition2}">
condition2為true
</c:when>
<c:otherwise>
condition1和condition2都為false
</c:otherwise>
</c:choose>
範例說明:當condition1為true時,會顯示「condition1為true」;當condition1為false且condition2為true時,會顯示「condition2為true」,如果兩者都為false,則會顯示「condition1和condition2都為false」。
注意:若condition1和condition2的運算結果都為true時,此時只會顯示"condition1為true"。
限制說明:
a、<c:when>和<c:otherwise>標簽必須在<c:choose>和</c:choose>之間使用。
b、在同一個<c:choose>中,<c:otherwise>必須是最後一個標簽,且只能有一個<c:otherwise>標簽。<c:when>可以有多個。
c、在同一個<c:choose>中,當所有<c:when>的test都為false時,才執行<c:otherwise>的本體內容。
三、迭代操作
1、<c:forEach>
作用:為循環控制,它可以將集合(Collection)中的成員循序瀏覽一遍。運作方式為當條件符合時,就會持續重復執行<c:forEach>的本體內容。
語法1:迭代一個集合對象中的所有成員
<c:forEach items="collection" [var="varName"] [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"] />
...本體內容
</c:forEach>
語法2:迭代指定次數
<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin" end="end" [step="step"]>
...本體內容
</c:forEach>
屬性說明:
items:被迭代的集合對象。
var:存放當前指到的集合對象中的成員。
varStatus:存放當前指到的成員的相關信息。(index:當前指到的成員的索引;count:當前總共指到成員的總數;first:當前指到的成員 是否為第一個成員;last:當前指到的成員是否為最後一個成員)。
begin:迭代開始的位置,默認為0。
end:迭代結束的位置,默認為最後。
step:每次迭代的間隔數,默認為1。
範例:
<%
int atts[] = {1,2,3,4,5,6,7,8,9,10};
request.setAttribute("atts", atts);
%>
<c:forEach items="${atts}" var="item" begin="0" end="9" step="1" >
${item}</br>
</c:forEach>
此標簽也可以用於普通的循環控制,與for循環一樣。如:
<c:forEach begin="1" end="10" var="item" >
${item}</br>
</c:forEach>
2、<c:forTokens>
作用:用指定分隔符分隔一字元串,並迭代分隔後的數組。
語法: <c:forTokens items="stringOfTokens" delims="delimiters" [var="varName"] [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"] >
本體內容
</c:forTokens>
屬性說明:
items:被分隔並迭代的字元串。
delims:用來分隔字元串的字元。
var:存放當前指到的成員。
varStatus:存放當前指到的成員的相關信息。(index:當前指到的成員的索引;count:當前總共指到成員的總數;first:當前指到的成員 是否為第一個成員;last:當前指到的成員是否為最後一個成員)。
begin:迭代開始的位置,默認為0。
end:迭代結束的位置,默認為最後。
step:每次迭代的間隔數,默認為1。
範例1:
<c:forTokens items="A,B,C,D,E" delims="," var="item" >
${item}
</c:forTokens>
用「,」號分隔字元串,並迭代輸出分隔後的字元串數組,輸出結果為「ABCDE」。
範例2:
<c:forTokens items="A,B;C-D,E" delims=",;-" var="item" >
${item}
</c:forTokens>
delims中指定了三個分隔符「,」、「;」和「-」,可見我們一次可以設定所有想當做分隔字元串用的字元。輸出結果依然為「ABCDE」。
四、URL操作
1、<c:import>
作用:將其他靜態或動態文件包含到本身JSP網頁中。不但可以包含同一個web application下的文件,還可以包含其他web application或其他網站的文件。
語法:
<c:import url="url" [var="varName"] [scope="{page|request|session|application}"] >
[<c:param name="paramName" value="paramValue"/>]
</c:import>
屬性說明:
url:要包含至本身JSP網頁的其他文件的URL。必選
var:將包含進來的其他文件以字元串的形式存放到指定的變數中。可選
scope:var變數的作用范圍。可選
<c:param>:可選子標簽,用於向包含進來的其他網頁文件傳遞參數。
範例:
<c:import url="http://java.sun.com" >
<c:param name="test" value="1234" />
</c:import>
說明:當<c:import>標簽中未指定var變數時,會直接將包含進來的其他網頁文件內容顯示出來,如果指定了var變數,則會將內容存放到var變數中,不顯示。
2、<c:url>
作用:生成一個URL。
語法:
<c:url value="url" [context="expression"] [var="name"] [scope="scope"]>
[<c:param name="expression" value="expression"/>]
</c:url>
範例1:
<a href="<c:url value=index.jsp'/>">index page</a>
在<a>超鏈接標簽中生成一個URL,指向index.jsp。
範例2:
<c:url value="index.jsp">
<c:param name="keyword" value="${searchTerm}"/>
<c:param name="month" value="02/2003"/>
</c:url>
生成一個URL,並傳遞參數,生成的結果為index.jsp?keyword=*&month=02/2003,*代表傳遞的searchTerm的值。
3、<c:redirect>
作用:可以將客戶端的請求從一個JSP網頁導向到其他文件。
語法:
<c:redirect url="url">
[<param name="paramName" value="paramValue">]
</c:redirect>
將請求導向URl指向的其他文件。
五、I18N格式化標簽庫
使用I18N格式化標簽之前,需先插入以下指令:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
1、<fmt:formatNumber>
作用:將數字格式化成數字、貨幣、百分比
語法:
<fmt:formatNumber value="value" [var="varName"] [type="{number|curreny|percent}"] [maxFractionDigits="3"] [groupingUsed="{true|false}"]/>
屬性說明:
value:需要進行格式化的值
var:值的另一個變數聲明
maxFractionDigits:保留的小數點個數
2、<fmt:parseNumber>
作用:將字元串型的數字、貨幣、百分比格式化成數字
語法:
<fmt:parseNumber value="¥6789.36" [var="result"] [type="{number|curreny|percent}"] >
屬性說明:
value:需要進行格式化的值
var:值的另一個變數聲明
3、<fmt:formatDate>
作用:格式化時間和日期
4、<fmt:parseDate>
作用:將字元串形式的時間和日期轉換成日期時間類型。
5、<fmt:setTimeZone>
作用:在JSP 網頁中設置默認時區。
6、<fmt:timeZone>
作用:在JSP網頁中為該標簽體內的代碼段設置時區。
7、<fmt:setLocale>
作用:在JSP 網頁中設置語言地區。
8、<fmt:requestEncoding>
作用:在JSP 網頁中設置請求所採用的編碼方式,等價於JSP中的request. setCharacterEncoding(String encoding)。
9、<fmt:setBundle>
作用:設置默認的消息資源。
10、<fmt:message>
作用:在指定的消息資源中按關鍵字取出相應的消息內容。
11、<fmt:param>
作用:在從消息資源中取出消息內容時,為消息內容設置動態參數。
12、<fmt:bundle>
作用:為該標簽體內的代碼段設置一個消息資源。
他們的區別:
EL相關概念JSTL一般要配合EL表達式一起使用,來實現在jsp中不出現java代碼段。所以我們先來學習EL表達式EL主要用於查找作用域中的數據,然後對它們執行簡單操作;它不是編程語言,甚至不是腳本編制語言。通常與 JSTL 標記一起作用,能用簡單而又方便的符號來表示復雜的行為。EL基本格式EL表達式的格式:用美元符號($)定界,內容包括在花括弧({})中;例如: ${loginInfoBean.suser}此外,您可以將多個表達式與靜態文本組合在一起以通過字元串並置來構造動態屬性值;例如:Hello {loginInfoBean.suser} ${loginInfoBean.spwd}EL語法組成-標識符EL表達式由標識符、存取器、文字和運算符組成。標識符用來標識存儲在作用域中的數據對象。EL 有 11 個保留標識符,對應於 11個EL隱式對象。除了11隱式對象外,假定所有其它標識符都用來標識作用域的變數。標識符例:${abc} 相當於<%=pageContext.findAttribute(「abc」)%>${og_1} <%=pageContext.findAttribute(「og_1」)%>…等等;就是說{}內的標識符除了11個保留字之外都表示作用域中的數據對應的名.${requestScope}中的requestScope是11個EL隱式對象之一,它不再表示作用域中數據,而是表示request作用域;EL隱藏對象pageContext PageContext 實例對應於當前頁面的處理pageScope 與頁面作用域屬性的名稱和值相關聯的Map類requestScope 與請求作用域屬性的名稱和值相關聯的Map類sessionScope 與會話作用域屬性的名稱和值相關聯的Map類applicationScope 與應用程序作用域屬性的名稱和值相關聯的Map類param 按名稱存儲請求參數的主要值的 Map 類paramValues 將請求參數的所有值作為 String 數組存儲的 Map 類Header 按名稱存儲請求頭主要值的 Map 類headerValues 將請求頭的所有值作為 String 數組存儲的 Map 類cookie 按名稱存儲請求附帶的 cookie 的 Map 類initParam 按名稱存儲 Web 應用程序上下文初始化參數的Map類EL存取器存取器用來檢索對象的特性或集合的元素。存取器: 通過 「[]」 或 「.」 符號獲取相關數據例:${userBean.suser} 或 ${userBean[「suser」]}//獲取輸出bean中的suser屬性值;${mcType[「id」]} //獲取map中key為id對應的值;EL運算符運算符允許對數據和文字進行組合以及比較。EL運算符:類別 運算符算術運算符 +、-、*、/(或 div)和 %(或 mod)關系運算符 ==(或eq)、!=(或ne)、<(或lt)、>(或gt)、<=(或le) 和 >=(或ge)邏輯運算符 &&(或 and)、||(或or)和 !(或 not)驗證運算符 empty驗證運算符(empty):對於驗證數據特別有用。empty 運算符採用單個表達式作為其變數(也即,${empty input}),並返回一個布爾值,該布爾值表示對表達式求值的結果是不是「空」值。求值結果為 null 的表達式被認為是空,即無元素的集合或數組。如果參數是對長度為零的 String 求值所得的結果,則 empty 運算符也將返回 true。EL文字文字表示固定的值 — 數字、字元、字元串、布爾型或空值。在 EL 表達式中,數字、字元串、布爾值和 null 都可以被指定為文字值。字元串可以用單引號或雙引號定界。布爾值被指定為 true 和 falseJSTL是什麼JSTL(JSP Standard Tag Library,JSP標准標簽庫)是一個不斷完善的開放源代碼的JSP標簽庫,是由apache的jakarta小組來維護的。JSTL1.0 由四個定製標記庫(core、format、xml 和 sql)和一對通用標記庫驗證器組成。core 標記庫提供了定製操作,通過限制了作用域的變數管理數據,以及執行頁面內容的迭代和條件操作。它還提供了用來生成和操作 URL 的標記。format 標記庫定義了用來格式化數據(尤其是數字和日期)的操作。它還支持使用本地化資源束進行JSP頁面的國際化。xml 庫包含一些標記,這些標記用來操作通過XML表示的數據,而 sql 庫定義了用來查詢關系資料庫的操作。 兩個 JSTL 標記庫驗證器允許開發人員在其 JSP 應用程序中強制使用編碼標准。如果要使用JSTL,則必須引用jstl.jar和 standard.jar兩個包。為什麼要用JSTL我們JSP用於開發信息展現頁非常方便;也可以嵌入java代碼(scriptlet、表達式和聲明)代碼用來實現相關邏輯控制。看下面程序。但這樣做會帶來如下問題:jsp維護難度增加;出錯提示不明確,不容易調試;分工不明確;(即jsp開發者是美工,也是程序員);最終增加程序的開發成本;解決上面的問題可以使用定製標記庫,JSTL使JSP開發者可以減少對腳本元素的需求,甚至可以不需要它們,從而避免了相關的維護成本。使分工更明確。<% if (session.getAttribute(「user」).equals(「member」)) {%><p>Welcome, member!</p><% } else { %><p>Welcome, guest!</p><% } %>JSTL一般配合EL一起使用,因此先看看EL.JSTL部署在EE應用程序中部署JSTL有兩種方式:已存在的工程上部署將jstl.jar和standard.jar兩個包考到現有工程WebRoot / WEB-INF / lib 目錄下將相關的 .tld文件考到現有工程 WebRoot /WEB-INF 目錄下;也可通過eclipse在已存在
③ jsp中JSTL里的<c:import>用法
把<c:import url="/test.jsp" var="imp"></c:import>中的var="imp"去掉,加上var使其成為一個pageScope的變數,只有在明確使用${imp}時才會有效. :-)
④ 如何在JSTL標准標簽中定義變數
在標簽里定義變數可以用<c:set>標簽定義。var是變數名,value是值。有個scope屬性是專定義作用范圍的,屬由小到大為pageContext,request,session,application,默認為pageContext,相當於pageContext.setAttrubute()方法。在jsp頁面中可以用內置對象pageContext進行讀取。例如:
<c:set var="url" value="123"></c:set>
<%
out.println("<a href='"+pageContext.getAttribute("url")+"'>點擊</a>");
%>
⑤ jsp載入時怎麼獲取後台list集合並遍歷
1、首先,需要JSTL-1.2的jar包,自行網路搜索下載。
⑥ JSTL包括哪五部分
標簽庫和EL(Expression Language表達式語言)語言。標簽庫目前支持四種標簽:Core標簽庫、流控制標簽、版循環控制標簽、導入權文件和URL
JSTL的優點
1、 在應用程序伺服器之間提供了一致的介面,最大程序地提高了WEB應用在各應用伺服器之間的移植。
2、 簡化了JSP和WEB應用程序的開發。
3、 以一種統一的方式減少了JSP中的scriptlet代碼數量,可以達到沒有任何scriptlet代碼的程序。在我們公司的項目中是不允許有任何的scriptlet代碼出現在JSP中。
4、 允許JSP設計工具與WEB應用程序開發的進一步集成。相信不久就會有支持JSTL的IDE開發工具出現。
⑦ JavaScript中可以使用JSTL標簽嗎
這個是通抄過標簽產生一堆js代碼,產襲生的js代碼和原來的js聯用,就出效果。
javasript 中不能使用jstl標簽,是頁面經過解釋後,將jstl轉換成靜態代碼,你這里就是js代碼。
javascript是客戶端腳本語言,是運行在客戶端的,客戶端怎麼能解釋jstl標簽啊,那是伺服器端做的事。
你要用的話,是
<script type="text/javascript">
<c:forEach items="${sessionScope.treeInfo}" var="tree">
tree.nodes[${tree.parentId}_${tree.id}] =
text:${tree.text};icon:${tree.icon};url:${tree.url};
</c:forEach>
</script>
放到script標簽里就可以了,會被解析成js代碼。
這段要放在你引用的js後面。
⑧ 關於JSP中JSTL標簽庫的問題!!!
什麼是標簽庫?
JSP標簽庫(也稱自定義標簽庫)可看成是一種通過JavaBean生成基於XML的腳本的方法。從概念上講,標簽就是很簡單而且可重用的代碼結構。比方說,在我們最新發布的JSPKit(在JSP Insider內)中,使用XML標簽實現了對XML文檔的輕松訪問。請看以下的清單A。
清單A:執行XML/XSL 轉換的示例標簽及其所在的HTML頁面
<%@ taglib uri="http://www.jspinsider.com/jspkit/JAXP" prefix="JAXP"%>
<JAXP:TransformerTag>
<JAXP:XMLFile>c:/xml/example.xml</JAXP:XMLFile>
<JAXP:XSLFile>c:/xml/example.xsl</JAXP:XSLFile>
</JAXP:TransformerTag>
以上的示例使用了簡單的標簽來訪問處在幕後的更強大代碼,標簽部分的語句首先裝載了一個XML文件,然後應用了一個XSL文件來將XML文件中的內容轉換成某個表現格式,並發送給客戶端,這一切僅僅只是用了一個很簡單的標簽。定製標簽使得JSP項目中很容易創建重用的開放源代碼模塊,而你所需要的只是標簽庫和它的文檔說明。
標簽庫的重要特性
1.易於安裝在多個項目上
標簽很容易從一個JSP項目遷移到其他項目。一旦建立了一個標簽庫,則只需要將所有的東西打包為一個JAR文件,你就可以在任何的JSP項目中重新使用。因為標簽可以重新使用,標簽庫可以輕松地用於你自己的項目,所以標簽庫越來越通行。目前,最好的標簽資源可以在JSPTags.com這個站點找到。
2.擴展JSP 標簽庫可以具備JSP規范(JSP 1.2)中的任何特性和功能,你可以無限制地擴展和增加JSP的功能,而無需要等待下一版本JSP的出現。例如,你對JSP的include調用不太滿意。你可以建立自己的include標簽,該標簽執行的是你自己的規范。
3.容易維護
標簽庫使得JSP的web應用程序非常易於維護,原因有:
(1)標簽應用簡單,對任何人而言都很容易使用、易於理解。
(2)所有的程序邏輯代碼都集中放在的標簽處理器和JavaBeans中。這意味著你在升級代碼時,無需要對每個使用該代碼的頁面進行修改,你只需要修改集中的代碼文件便可。
(3)如果需要加入新的功能,你也無需修改任何已經存在的頁面,可以在標簽中加入額外的屬性,從而引進新的行為,而其它舊的屬性不變,這樣所有舊的頁面還可以正常工作。 例如你有一個讓所有文本變藍的標簽:
<BlueText>My Text</BlueText>
但在後來項目中,你又想讓藍色變暗。你可以保留原有的標簽,只要為其增加一個新的屬性:shade ,如下所示:
<BlueText shade="teal">My Text</BlueText>
所有舊的標簽仍然可以產生藍色的文本,但現在你可以使用同一標簽來產生變暗的藍色文本了。
(4)標簽提升了代碼的重用性。那些經過多次測試和使用的代碼肯定具有更少的bug。所以,使用定製標簽的JSP頁面也同樣具有更少的缺陷,維護起來自然方便多了。
4.快速的開發時間
標簽庫提供一個簡單的方式來重用代碼。在伺服器端的語言中,其中一個標準的重用代碼方式是使用模板。相對於使用模板庫,標簽庫是一個更好的解決辦法。使用模板庫,你必須為每個項目修改模板或者且建立嚴格的界面,而標簽庫則沒有這些限制,並且擁有所有面向對象的好處,可以做到靈活和更有擴展性,而且,通過重用代碼,你可以花費更少的時間來做開發,更多的時間可以用在設計你的web應用上。標簽庫的介面也很簡單,非常容易做插入、使用和調試。
標簽的組成結構
雖然標簽庫非常易於使用,不過要建立一個標簽庫的內部實現機制還是頗復雜的,起碼要比建立一個簡單的JavaBean復雜。這個復雜是來自於標簽庫是由幾部分構成的。不過,你只需要掌握了Java和JSP的知識就夠了。
一個簡單的標簽由下面的元素構成:
1.JavaBean:為了得到Java與生具來的面向對象的好處,可重用的代碼應該放到一個獨立的代碼容器中,也就是JavaBean。這些JavaBeans並不是標簽庫必不可少的一部分,但它們是標簽庫用來執行所分配任務的基礎代碼模塊。
2.標簽處理器:標簽處理器是標簽庫的真正核心。一個標簽處理器(tag handler)引用它所需要的任何外部資源(JavaBean)並且負責訪問JSP頁面的信息(PageContext對象)。而JSP頁面則把頁面上設置的標簽屬性和標簽體中的內容都傳遞給標簽處理器,當標簽處理器完成其處理過程後,它就會把處理後的輸出結果回送給JSP頁面做進一步處理。
3.標簽庫描述符(TLD文件):這是一個簡單的XML文件,它記錄著標簽處理器的屬性、信息和位置等信息。JSP容器通過這個文件來得知從哪裡及如何調用一個標簽庫。
4.Web站點的web.xml文件:這是Web站點的初始化文件,在這個文件中,需要定義了Web站點中用到的自定義標簽,以及用來描述每個自定義標簽的tld文件。
5.發布文件(WAR或JAR文件):如果你想重用自定義標簽的話,你需要一個方法來將它由一個項目遷移到其他項目中去。將標簽庫打包為一個JAR文件是一個簡單而且有效的方式。
6.JSP頁面上的標簽庫聲明:要在JSP頁面中的使用某個自定義標簽的話,需要使用標簽庫標示符在頁面上進行聲明。
看來要做的工作很多,剛開始用的時候當然會有點棘手,不過其實並不是很難。它的要點並不在於編碼,而是在於如何將各部分正確地組織起來。這種層次性的結構是很重要的,它令標簽的使用靈活和更容易轉移。更重要的事,這些層次可以讓整個建立標簽庫的過程都能通過JSP IDE(JSP的集成開發環境)自動完成。JSP IDE更可以自動完成創建定製標簽的大部分工作,而你自己則只需要負責建立代碼和標簽處理器。
(注意:一個標簽處理器僅定義一個自定義標簽;一個標簽庫是幾個處理相同任務的標簽處理器的集合)
建立你的第一個標簽
以下將一步一步地教你如何建立自定義的標簽,具體的例子是擴展JSP,令它擁有自己的HTML編碼功能。這個功能將所有的<和>字元用 HTML代碼來代替。它可以很容易地擴展為做其它的編碼處理。為了簡化,這個例子只解釋了建立自定義標簽的基本要素。
創建JavaBean
代碼中的任何可重用部分都應該放到一個JavaBean中。這一點是很重要的。這樣你就可以在其他項目中重用這些代碼了。由於任何放置在標簽處理器內的代碼在標簽外都是不可以重用的,因此將可重用的代碼部分獨立開來是很重要的。在這個例子總,為HTML編碼的邏輯是常用的,因此放到JavaBean中,請參看清單B
清單B:HTML編碼JavaBean
/* HTML_Format.java */
public class HTML_Format extends Object implements java.io.Serializable {
/** 創建新的HTML_Format */
public HTML_Format() {}
/** 將一個字元串中所有的所有 < 和 > 字元用響應的HTML編碼代替 */
public String HTML_Encode(String as_data)
{
int li_len = as_data.length();
/*string buffer的長度要比原來的字元串長*/
StringBuffer lsb_encode = new StringBuffer(li_len + (li_len/10));
/* 循環替換全部的< 和 > 字元 */
for( int li_count = 0 ; li_count < li_len ; li_count++)
{ String ls_next = String.valueOf(as_data.charAt(li_count));
if (ls_next.equals("<")) ls_next = "<";
if (ls_next.equals(">")) ls_next = ">";
lsb_encode.append( ls_next );
}
return( lsb_encode.toString() );
}
}
創建標簽處理器
標簽處理器的代碼請參看清單C:
清單C:HTML編碼標簽處理器
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class HTML_FormatTag extends BodyTagSupport
{
/* 1) 在標簽末將會調用這個函數 */
public int doEndTag() throws JspTagException
{
try
{ /* 2)得到標簽中的文本 */
BodyContent l_tagbody = getBodyContent();
String ls_output = "";
/* 3)如果標簽體有文本,就處理它 */
if(l_tagbody != null)
{ HTML_Format l_format = new HTML_Format();
/* 3a) 將標簽體的內容轉換為一個字元串 */
String ls_html_text = l_tagbody.getString();
ls_output = l_format.HTML_Encode(ls_html_text);
}
/* 4)將結果寫回到數據流中 */
pageContext.getOut().write(ls_output.trim());
}
catch (IOException e)
{ throw new JspTagException("Tag Error:" + e.toString());
}
/* 讓JSP繼續處理以下頁面的內容 */
return EVAL_PAGE;
}
}
這個處理很簡單,它包括有:
1.讀入位於開始和結束標簽間的文本
2.調用html編碼函數
3.將結果返回到JSP頁面。
創建標簽描述符
我們需要描述自定義標簽以讓系統知道如何處理。該描述文件的後綴為.tld,TLD文件通常就以標簽處理器命名,並存放在「/WEB-INF/」目錄之下。請參看清單D。
清單D:HTML編碼標簽描述器
<?xml version="1.0" encoding="UTF-8" ?>
<!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>HTML_FormatTag</SHORTNAME>
<URI></URI>
<INFO>HTML Encoding Tag </INFO>
<TAG>
<NAME>HTMLEncode</NAME>
<TAGCLASS>HTML_FormatTag</TAGCLASS>
<INFO>Encode HTML</INFO>
</TAG>
</TAGLIB>
更新Web XML文件
現在可以告訴JSP容器如何使用標簽庫了。為此要修改web.xml文件,具體說來是要在其中加入一個taglib的項目來注冊該標簽庫,並為標簽分配一個URI。URI是Web站點上唯一應用於這一特定標簽的索引。由於標簽今後還可能用在不同的Web站點上,所以你最好採用完整的URL和/或者包名字(package name)來保證這一唯一性。這個例子是簡化了,示例代碼請參看清單E。
清單E:修改web.xml文件
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<WEB-APP>
<TAGLIB>
<TAGLIB-URI>
HTMLEncode
</TAGLIB-URI>
<TAGLIB-LOCATION>
/WEB-INF/HTML_FormatTag.tld
</TAGLIB-LOCATION>
</TAGLIB>
</WEB-APP>
使用新的標簽
自定義的標簽設置好後,就可以用在你的JSP頁面上了。要做到這一點,只需要在頁面上使用taglib指示命令聲明所要採用的標簽即可。標簽通過其唯一的 URI被索引,然後被分配給一個名字空間前綴(prefix)。這一前綴並沒有什麼特別的意義,只要它不與其它的名字空間沖突便可,可以任意。請參看以下的清單F和G。
清單F:在一個JSP頁面上使用HTML編碼標簽
<%@ taglib uri="HTMLEncode" prefix="Examples" %>
<PRE>
<?XML:NAMESPACE PREFIX = Examples /><Examples:HTMLEncode>
< Hello , Simple sample >
</Examples:HTMLEncode>
</PRE>
清單G:範例代碼的輸出
< Hello , Simple sample >
which displays as:
< Hello , Simple sample >
通過這個標簽,我就將該頁面的所有代碼編碼了。所有的自定義標簽都是在伺服器上處理的。這意味著你將不會在輸出的頁面上看到自定義的標簽。
正如你所看到的那樣,建立標簽並非難事。最麻煩的是學習標簽處理器的整個細節。這是一個很強大的功能,我們不過是觸及了皮毛。由於這一過程需要採取的步驟很多,所以剛入門的JSP程序員可能在建立標簽的時候會覺得很困惑。
結論
標簽庫是JSP最重要的特性之一,它還處在不斷的發展中。它的確是一個新事物,因此還沒有被廣泛採用,不過自定義標簽庫已經剝去了它的神秘面紗,越來越多的開發者也開始關注和使用它了。在2001年末,可預料標簽庫將是許多JSP項目中的一個很常見的特性。
在這篇文章中只簡要地討論了標簽庫的好處。標簽庫實際上還有許多其它強大的功能。標簽庫促使JSP開發進入了前所未有的新天地。對JSP開發人員來說這確實是一種很令人振奮的新技術,因為他們得到了一個可將JSP轉到各個應用並且建立任何類型web應用的工具。標簽庫讓JSP變成了最豐富、最具動態開發能力的、強大的Web編程環境。它的功能只受我們的想像和創造力限制。