JSTL(JavaServer Pages Standard Tag Library,JSP標準標籤庫)是一個不斷完善的開放原始碼的JSP標籤庫,是由apache的jakarta小組來維護的。JSTL只能運行在支持JSP1.2和Servlet2.3規範的容器上,如tomcat 4.x。在JSP 2.0中也是作為標準支持的。
JSTL 1.0 發布於 2002 年 6 月,由四個定製標記庫(core、format、xml 和 sql)和一對通用標記庫驗證器(ScriptFreeTLV 和 PermittedTaglibsTLV)組成。core 標記庫提供了定製操作,通過限制了作用域的變數管理數據,以及執行頁面內容的疊代和條件操作。它還提供了用來生成和操作 URL 的標記。顧名思義,format 標記庫定義了用來格式化數據(尤其是數字和日期)的操作。它還支持使用本地化資源束進行 JSP 頁面的國際化。xml 庫包含一些標記,這些標記用來操作通過 XML 表示的數據,而 sql 庫定義了用來查詢關係資料庫的操作。
如果要使用JSTL,則必須將jstl.jar和 standard.jar檔案放到classpath中,如果你還需要使用XML processing及Database access (SQL)標籤,還要將相關JAR檔案放到classpath中,這些JAR檔案全部存在於下載回來的zip檔案中。
基本介紹
使用條件,優點,詳細介紹,隱式對象,存取器,運算符,文字,變數標記,輸出,常用函式,結束語,版本更新歷史,
使用條件
jstl帶來的優雅編程體驗人所皆知,在java社區蒸蒸日上的今天使用jstl已無需考慮很多問題,我們可以用myeclipse等java集成開發環境輕鬆搭建一個jstl的web項目。即便有了myeclipse這么得力的工具幫我們快速開發web項目,但是有一些知識我們必須了解的 ---- 那就是jstl與servlet版本,以及jsp版本之間的依賴關係。
以下列出jstl各個版本與jsp及servlet版本之間的依賴關係。
版本號 | JSTL 版本 | 要求(必須滿足此條件) | 獲取Taglib途徑 |
Standard 1.2 | JSTL 1.2 (尚未經過JCP認證) | Servlet 2.5, JavaServer Pages 2.1 | subversion |
Standard 1.1 | JSTL 1.1 | Servlet 2.4, JavaServer Pages 2.0 | 下載 |
Standard 1.0 | JSTL 1.0 | Servlet 2.3, JavaServer Pages 1.2 | 下載 |
優點
1、 在應用程式伺服器之間提供了一致的接口,最大程度地提高了WEB套用在各套用伺服器之間的移植。
2、 簡化了JSP和WEB應用程式的開發。
詳細介紹
JSP 標準標籤庫(JSP Standard Tag Library,JSTL)是一個實現 Web應用程式中常見的通用功能的定製標記庫集,這些功能包括疊代和條件判斷、數據管理格式化、XML 操作以及資料庫訪問。在 developerWorks 上其新系列的第一篇文章中,軟體工程師Mark Kolb 向您展示了如何使用 JSTL 標記來避免在 JSP 頁面中使用腳本編制元素。您還將了解如何通過從表示層刪除原始碼來簡化軟體維護。最後,您將了解 JSTL 經過簡化的表達式語言,它允許在不必使用功能齊全的程式語言的情況下對 JSTL 操作指定動態屬性值。
JavaServer Pages(JSP)是用於 J2EE 平台的標準表示層技術。JSP 技術提供了用於執行計算(這些計算用來動態地生成頁面內容)的腳本編制元素和操作。腳本編制元素允許在 JSP 頁面中包括程式原始碼,在為回響用戶請求而呈現頁面時可以執行這些原始碼。操作將計算操作封裝到很象 HTML 或 XML 標記的標記中,JSP 頁面的模板文本通常包含這些標記。JSP 規範只將幾種操作定義成了標準,但從 JSP 1.1 開始,開發人員已經能夠以定製標記庫的方式創建其自己的操作了。
JSP 標準標記庫(JSTL)是 JSP 1.2 定製標記庫集,這些標記庫實現大量伺服器端 Java應用程式常用的基本功能。通過為典型表示層任務(如數據格式化和疊代或條件內容)提供標準實現,JSTL 使 JSP 作者可以專注於特定於應用程式的開發需求,而不是為這些通用操作“另起爐灶”。
當然,您可以使用 JSP 腳本編制元素(scriptlet、表達式和聲明)來實現此類任務。例如,可以使用三個 scriptlet 實現條件內容,清單 1 中著重顯示了這三個 scriptlet。但是,因為腳本編制元素依賴於在頁面中嵌入程式原始碼(通常是 Java 代碼),所以對於使用這些腳本編制元素的 JSP 頁面,其軟體維護任務的複雜度大大增加了。例如,清單 1 中的 scriptlet 示例嚴格地依賴於花括弧的正確匹配。如果不經意間引入了一個語法錯誤,則條件內容中的嵌套其它 scriptlet可能會造成嚴重破壞,並且在 JSP容器編譯該頁面時,要使所產生的錯誤信息有意義可能會很困難。
清單 1. 通過 scriptlet 實現條件內容
<% if (user.getRole() == "member")) { %>
<p>Welcome, member!</p>
<% } else { %>
<p>Welcome, guest!</p>
<% } %>
修正此類問題通常需要相當豐富的編程經驗。儘管通常會由十分精通頁面布局和圖形設計的設計人員來開發和維護 JSP,但是同一頁面中的腳本編制元素出現問題時,需要程式設計師的介入。這種狀況將單個檔案中代碼的責任分擔給多人,因而使得開發、調試和增強此類 JSP 頁面成為很麻煩的任務。通過將常用功能包裝到定製標記庫的標準集合中,JSTL 使 JSP 作者可以減少對編制腳本元素的需求,甚至可以不需要它們,並避免了相關的維護成本。
JSTL 1.0
JSTL 1.0 發布於 2002 年 6 月,由四個定製標記庫( core 、 format 、 xml 和 sql )和一對通用標記庫驗證器( ScriptFreeTLV 和 PermittedTaglibsTLV )組成。 core 標記庫提供了定製操作,通過限制了作用域的變數管理數據,以及執行頁面內容的疊代和條件操作。它還提供了用來生成和操作 URL 的標記。顧名思義, format 標記庫定義了用來格式化數據(尤其是數字和日期)的操作。它還支持使用本地化資源束進行 JSP 頁面的國際化。 xml 庫包含一些標記,這些標記用來操作通過 XML 表示的數據,而 sql 庫定義了用來查詢關係資料庫的操作。
兩個 JSTL 標記庫驗證器允許開發人員在其 JSP應用程式中強制使用編碼標準。可以配置 ScriptFreeTLV 驗證器以在 JSP 頁面中禁用各種類型的 JSP腳本元素― scriptlet、表達式和聲明。類似地, PermittedTaglibsTLV 驗證器可以用來限制可能由應用程式的 JSP 頁面訪問的定製標記庫集(包括 JSTL 標記庫)。
儘管 JSTL 最終將會成為 J2EE 平台的必需組件,但只有少數應用程式伺服器包括它。JSTL 1.0 的參考實現可作為 Apache軟體基金會(Apache Software Foundation)的 Jakarta Taglibs項目(請參閱 參考資料)的一部分而獲得。可以將該參考實現中的定製標記庫合併到任何支持 JSP 1.2 和 Servlet 2.3 規範的伺服器,以添加對 JSTL 的支持。
在JSTL1.0的時候,在頁面顯示數據必須用<c:out>來進行,然而在JSTL1.1中,由於JSP2.0規範已經默認支持EL表達式,因此可以直接在JSP頁面使用表達式,看下面一個例子
<c:out value="${sessionScope.anyValue}" default="no value" escapeXml="false"/>
在EL表達式尚未出現之前,Struts1中一直用<bean:write>輸出變數內容
表達式語言
在 JSP 1.2 中,可以使用靜態字元串或表達式(如果允許的話)指定 JSP 操作的屬性。例如,在清單 2 中,對 <jsp:setProperty> 操作的 name 和 property 屬性指定了靜態值,而用表達式指定了其 value 屬性。這個操作的效果是將請求參數的當前值賦予命名的 bean 特性。以這種形式使用的表達式被稱為 請求時屬性值(request-time attribute value),這是構建到 JSP 規範中的用於動態指定屬性值的唯一機制。
清單 2. 合併請求時屬性值的 JSP 操作
<jsp:setProperty name="user" property="timezonePref"
value='<%= request.getParameter("timezone") %>'/>
因為請求時屬性值是用表達式指定的,所以它們往往有和其它腳本元素一樣的軟體維護問題。因此,JSTL 定製標記支持另一種用於指定動態屬性值的機制。可以用簡化的表達式語言(EL)而不使用完整的 JSP 表達式來指定 JSTL 操作的屬性值。EL 提供了一些標識符、存取器和運算符,用來檢索和操作駐留在 JSP容器中的數據。EL 在某種程度上以 EcmaScript(請參閱 參考資料)和 XML 路徑語言(XML Path Language,XPath)為基礎,因此頁面設計人員和程式設計師都應該熟悉它的語法。EL 擅長尋找對象及其特性,然後對它們執行簡單操作;它不是程式語言,甚至不是腳本編制語言。但是,與 JSTL 標記一起使用時,它就能使用簡單而又方便的符號來表示複雜的行為。EL表達式的格式是這樣的:用美元符號($)定界,內容包括在花括弧({})中,如清單 3 所示。
清單 3. 說明 EL表達式定界符的 JSTL 操作
<c:out value="${user.firstName}"/>
清單 4. 組合靜態文本和多個 EL表達式以指定動態屬性值
<c:out value="Hello ${user.firstName} ${user.lastName}"/>
限制了作用域的變數
JSP API 通過 <jsp:useBean> 操作允許從 JSP容器內的四個不同作用域中存儲和檢索數據。JSTL 通過提供用於指定和除去這些作用域中的對象的附加操作來擴展這一能力。此外,EL 提供將這些對象作為限制了作用域的變數進行檢索的內置支持。特別地,任何出現在 EL表達式中但不對應於任何 EL 隱式對象的標識符,都被自動假定為引用存儲在四個 JSP作用域的其中某箇中的對象,這四個作用域是:
頁面作用域
請求作用域
會話作用域
應用程式作用域
您可能還記得,只有在為特定請求處理頁面期間才能檢索存儲在該頁面作用域中的對象。如果對象是存儲在請求作用域中的,可以在處理所有參與處理某請求的頁面期間檢索這些對象(譬如在對某個請求的處理中遇到了一個或多個 <jsp:include> 或 <jsp:forward> 操作)。如果對象是存儲在會話作用域中的,則在與 Web應用程式的互動式會話期間,可以由用戶訪問的任何頁面檢索它(即,直到與該用戶互動相關聯的 HttpSession 對象無效為止)。可以由任何用戶從任何頁面訪問存儲在應用程式作用域中的對象,直到卸載 Web應用程式本身為止(通常是由於關閉 JSP容器所致)。
通過將字元串映射為期望作用域中的對象來將對象存儲到該作用域。然後,就可以通過提供相同字元串來從該作用域檢索該對象。在作用域的映射中查找字元串,並返回被映射的對象。在 Servlet API 中,將此類對象稱為相應作用域的 屬性。但是,在 EL 的上下文中,也將與屬性相關聯的字元串看作變數的名稱,該變數通過屬性映射的方式獲得特定的值。
在 EL 中,與隱式對象無關聯的標識符被認為是存儲在四個 JSP作用域中的名稱對象。首先對頁面作用域檢查是否存在這樣的標識符,其次對請求作用域、然後對會話作用域、最後對應用程式作用域依次進行這樣的檢查,然後測試該標識符的名稱是否與存儲在該作用域中的某個對象的名稱匹配。第一個這樣的匹配作為 EL標識符的值被返回。通過這種方法,可以將 EL標識符看作引用限制了作用域的變數。
從更技術的方面來說,沒有映射到隱式對象的標識符是用 PageContext 實例的 findAttribute() 方法求值的,該實例表示對頁面的處理,在該頁面上,當前正在處理用於請求的表達式。標識符的名稱作為參數傳遞給這個方法,然後該方法依次在四個作用域中搜尋具有相同名稱的屬性。並將所找到的第一個匹配項作為 findAttribute() 方法的值返回。如果未在這四個作用域中找到這樣的屬性,則返回 null 。
最終,限制了作用域的變數是四個 JSP 作用域的屬性,這些屬性具有可以用作 EL標識符的名稱。只要對限制了作用域的變數賦予由字母數字組成的名稱,就可以通過 JSP 中提供的用於設定屬性的任何機制來創建它們。這包括內置的 <jsp:useBean> 操作,以及由 Servlet API 中的幾個類定義的 setAttribute() 方法。此外,四個 JSTL 庫中定義的許多定製標記本身就能夠設定作為限制了作用域的變數使用的屬性值。
隱式對象
表 1 中列出了 11 個 EL 隱式對象的標識符。不要將這些對象與 JSP 隱式對象(一共只有九個)混淆,其中只有一個對象是它們所共有的。
表 1. EL 隱式對象
類別標識符描述
JSP pageContext PageContext 實例對應於當前頁面的處理
作用域pageScope 與頁面作用域屬性的名稱和值相關聯的 Map 類
requestScope 與請求作用域屬性的名稱和值相關聯的 Map 類
sessionScope 與會話作用域屬性的名稱和值相關聯的 Map 類
applicationScope 與應用程式作用域屬性的名稱和值相關聯的 Map 類
請求參數 param 按名稱存儲請求參數的主要值的 Map 類
paramValues 將請求參數的所有值作為 String數組存儲的 Map 類
請求頭 header 按名稱存儲請求頭主要值的 Map 類
headerValues 將請求頭的所有值作為 String數組存儲的 Map 類
Cookie cookie 按名稱存儲請求附帶的 cookie 的 Map 類
初始化參數 initParam 按名稱存儲 Web應用程式上下文初始化參數的 Map 類
儘管 JSP 和 EL 隱式對象中只有一個公共對象( pageContext ),但通過 EL 也可以訪問其它 JSP 隱式對象。原因是 pageContext 擁有訪問所有其它八個 JSP 隱式對象的特性。實際上,這是將它包括在 EL 隱式對象中的主要理由。
接下來的四個映射用來獲取請求參數和請求頭的值。因為 HTTP 協定允許請求參數和請求頭具有多個值,所以它們各有一對映射。每對中的第一個映射返回請求參數或頭的主要值,通常是恰巧在實際請求中首先指定的那個值。每對中第二個映射允許檢索參數或頭的所有值。這些映射中的鍵是參數或頭的名稱,但這些值是 String 對象的數組,其中的每個元素都是單一參數值或頭值。
cookie 隱式對象提供了對由請求設定的 cookie 名稱的訪問。這個對象將所有與請求相關聯的 cookie 名稱映射到表示那些 cookie 特性的 Cookie 對象。
最後一個 EL 隱式對象 initParam 是一個映射,它儲存與 Web 應用程式相關聯的所有上下文的初始化參數的名稱和值。初始化參數是通過web.xml部署描述符檔案指定的,該檔案位於應用程式的 WEB-INF 目錄中。
存取器
結果是,對這些對象的特性或(在對象是數組和集合的情況下)對其元素的訪問通常是令人滿意的。就為了實現這種用途,EL 提供了兩種不同的存取器(點運算符( . )和方括弧運算符( [] )),也支持通過 EL 操作特性和元素。
點運算符通常用於訪問對象的特性。例如,在表達式${user.firstName} 中,使用點運算符來訪問 user標識符所引用對象的名為 firstName 的特性。EL 使用 Java bean 約定訪問對象特性,因此必須定義這個特性的 getter 方法(通常是名為 getFirstName() 的方法),以便表達式正確求值。當被訪問的特性本身是對象時,可以遞歸地套用點運算符。例如,如果我們虛構的 user 對象有一個實現為 Java 對象的 address 特性,那么也可以用點運算符來訪問這個對象的特性。例如,表達式${user.address.city} 將會返回這個地址對象嵌套的 city 特性。
方括弧運算符用來檢索數組和集合的元素。在數組和有序集合(也即,實現了 java.util.List 接口的集合)的情況下,把要檢索的元素的下標放在方括弧中。例如,表達式${urls[3]} 返回 urls標識符所引用的數組或集合的第四個元素(和 Java 語言以及 JavaScript 中一樣,EL 中的下標是從零開始的)。
對於實現 java.util.Map 接口的集合,方括弧運算符使用關聯的鍵查找存儲在映射中的值。在方括弧中指定鍵,並將相應的值作為表達式的值返回。例如,表達式${commands["dir"]} 返回與 commands標識符所引用的 Map 中的 "dir" 鍵相關聯的值。
對於上述兩種情況,都可允許表達式出現在方括弧中。對嵌套表達式求值的結果將被作為下標或鍵,用來檢索集合或數組的適當元素。和點運算符一樣,方括弧運算符也可以遞歸套用。這使得 EL 能夠從多維數組、嵌套集合或兩者的任意組合中檢索元素。此外,點運算符和方括弧運算符還可以互操作。例如,如果數組的元素本身是對象,則可以使用方括弧運算符來檢索該數組的元素,並結合點運算符來檢索該元素的一個特性(例如 ${urls[3].protocol} )。
假定 EL 充當指定動態屬性值的簡化語言,EL 存取器有一個有趣的功能(與 Java 語言的存取器不同),那就是它們在套用於 null 時不拋出異常。如果套用 EL 存取器的對象(例如, ${foo.bar} 和 ${foo["bar"]} 中的 foo標識符)是 null ,那么套用存取器的結果也是 null 。事實證明,在大多數情況下,這是一個相當有用的行為,不久您就會了解這一點。
最後,點運算符和方括弧運算符可能實現某種程度的互換。例如,也可以使用 ${user["firstName"]} 來檢索 user 對象的 firstName 特性,正如可以用 ${commands.dir} 獲取與 commands 映射中的 "dir" 鍵相關聯的值一樣。
數據類型 | 示例用法 | 實際調用方法 |
JavaBean組件 | ${colorBean.red} ${colorBean["red"]} | colorBean.getRed() |
數組 | ${colorArray[2]} ${colorArray["2"]} | Array.get(colorArray, 2) |
List | colorList[2] colorList["2"] | colorList.get(2) |
Map | colorMap[red] colorMap["red"] | colorMap.get(pageContext.findAttribute("red")) colorMap.get("red") |
運算符
EL 還可以通過使用標識符和存取器,遍歷包含應用程式數據(通過限制了作用域的變數公開)或關於環境的信息(通過 EL 隱式對象)的對象層次結構。但是,只是訪問這些數據,通常不足以實現許多 JSP應用程式所需的表示邏輯。
最終,EL 還包括了幾個用來操作和比較 EL表達式所訪問數據的運算符。表 2 中匯總了這些運算符。
表 2. EL 運算符
類別運算符
算術運算符 + 、 - 、 * 、 / (或 div )和 % (或 mod )
關係運算符== (或 eq )、 != (或 ne )、 < (或 lt )、 > (或 gt )、 <= (或 le )和 >= (或 ge )
邏輯運算符 && (或 and )、 || (或 or )和 ! (或 not )
驗證運算符 empty
算術運算符支持數值的加法、減法、乘法和除法。還提供了一個求余運算符。註:除法和求余運算符都有替代的、非符號的名稱(為的是與 XPath 保持一致)。清單 5 中顯示了一個演示算術運算符用法的示例表達式。對幾個 EL表達式套用算術運算符的結果是將該算術運算符套用於這些表達式返回的數值所得的結果。
清單 5. 利用算術運算符的 EL 表達式
${item.price * (1 + taxRate[user.address.zipcode])}
清單 6. 利用關係和邏輯運算符的 EL 表達式
${(x >= min) && (x <= max)}
最後一種 EL運算符是 empty ,它對於驗證數據特別有用。 empty運算符採用單個表達式作為其變數(也即, ${empty input} ),並返回一個布爾值,該布爾值表示對表達式求值的結果是不是“空”值。求值結果為 null 的表達式被認為是空,即無元素的集合或數組。如果參數是對長度為零的 String 求值所得的結果,則 empty運算符也將返回 true 。
表 3 顯示了 EL 運算符的優先權。正如清單 5 和 6 所示,可以用圓括弧對表達式分組,高於普通的優先權規則。
表 3. EL運算符優先權(自頂到底,從左到右)
[] , .
()
unary - 、 not 、 ! 、 empty
* 、 / 、 div 、 % 、 mod
+ 、binary -
() <</code> 、 > 、 <= 、 >= 、 lt 、 gt 、 le 、 ge
== 、 != 、 eq 、 ne
&& 、 and
|| 、 or
文字
在 EL表達式中,數字、字元串、布爾值和 null 都可以被指定為文字值。字元串可以用單引號或雙引號定界。布爾值被指定為 true 和 false 。
Taglib偽指令
正如我們先前討論的,JSTL 1.0 包括四個定製標記庫。為了演示 JSTL 標記和表達式語言的互動,我們將研究幾個來自 JSTL core 庫的標記。和使用任何 JSP 定製標記庫一樣,必須在您想要使用這個庫標記的任何頁面中包括 taglib 偽指令。清單 7 顯示了用於這個特定庫的偽指令。
清單 7. 用於 JSTL core 庫 EL 版本的 taglib 偽指令
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
實際上,對應於 JSTL core 庫的 taglib 偽指令有兩種,因為在 JSTL 1.0 中,EL 是可選的。所有四個 JSTL 1.0 定製標記庫都有使用 JSP表達式(而不是 EL)指定動態屬性值的備用版本。因為這些備用庫依賴於 JSP 的更傳統的請求時屬性值,所以它們被稱為 RT庫,而那些使用表達式語言的則被稱為 EL 庫。開發人員用不同的 taglib 偽指令來區分每個庫的這兩個版本。清單 8 顯示了使用 core 庫的 RT 版本的偽指令。但是,由於我們討論的重點是 EL,所以首先需要這些偽指令。
清單 8. 用於 JSTL core 庫 RT 版本的 taglib 偽指令
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt" %>
變數標記
我們首先要考慮的 JSTL 定製標記是 <c:set> 操作。正如已經說明的,限制了作用域的變數在 JSTL 中起關鍵作用, <c:set> 操作提供基於標記的機制來創建和設定限制了作用域的變數。清單 9 中顯示了該操作的語法,其中 var 屬性指定了限制了作用域的變數的名稱, scope 屬性表明了該變數駐留在哪個作用域中, value 屬性指定了分配給該變數的值。如果指定變數已經存在,則簡單地將所指明的值賦給它。如果不存在,則創建新的限制了作用域的變數,並用該值初始化這個變數。
清單 9. <c:set> 操作的語法
<c:set var="name"
scope="scope"
value="expression"/>
scope 屬性是可選的,其預設值是 page 。
清單 10 中顯示了 <c:set> 的兩個示例。在第一個示例中,將會話作用域變數設定成 String 值。在第二個示例中,用表達式來設定數值:將頁面作用域內名為 square 的變數賦值為名為 x 的請求參數的值的平方。
清單 10. <c:set> 操作示例
<c:set var="timezone" scope="session" value="CST"/>
<c:set var="square" value="${param['x'] * param['x']}"/>
您還可以將限制了作用域的變數的值指定為 <c:set> 操作的主體內容,而不是使用屬性。使用這種方法,您可以重新編寫清單 10 中的第一個示例,如清單 11 所示。此外,正如我們馬上可以看到的, <c:set> 標記的主體內容本身也可以使用定製標記。 <c:set> 主體內生成的所有內容都將作為一個 String 值賦給指定變數。
清單 11. 通過主體內容指定 <c:set> 操作的值
<c:set var="timezone" scope="session">CST</c:set>
JSTL core 庫包含第二個用於管理限制了作用域的變數的標記 ― <c:remove> 。顧名思義, <c:remove> 操作是用來刪除限制了作用域的變數的,它獲取兩個屬性。 var 屬性指定待刪除變數的名稱, scope 屬性是可選的,它表示待刪除變數來自哪個作用域,預設為 page ,如清單 12 所示。
清單 12. <c:remove> 操作示例 <c:remove var="timezone" scope="session"/>
輸出
儘管 <c:set> 操作允許將表達式結果賦給限制了作用域的變數,但開發人員通常會希望只顯示表達式的值,而不存儲它。JSTL <c:out> 定製標記承擔這一任務,其語法如清單 13 所示。該標記對由其 value 屬性指定的表達式進行求值,然後列印結果。如果指定了可選屬性 default ,那么,在對 value 屬性的表達式求值所得結果為 null 或空 String 的情況下, <c:out> 將列印其值。
清單 13. <c:out> 操作的語法
<c:out value="expression"
default="expression"
escapeXml="boolean"/>
escapeXml 屬性也是可選的。它控制當用 <c:out> 標記輸出諸如“<”、“>”和“&”之類的字元(在 HTML 和 XML 中具有特殊意義)時是否應該進行轉義。如果將 escapeXml 設定為 true,則會自動將這些字元轉換成相應的 XML 實體(此處提到的字元分別轉換成 < 、 > 和 & )。
例如,假定有一個名為 user 的會話作用域變數,它是一個類的實例,該類為用戶定義了兩個特性: username 和 company 。每當用戶訪問站點時,這個對象被自動分配給會話,但直到用戶實際登錄後,才會設定這兩個特性。假定是這種方案,請考慮清單 14 中的 JSP 片段。在用戶登錄之後,這個片段將顯示單詞“Hello”,其後是他/她的用戶名和一個驚嘆號。但是,在用戶登錄之前,由這個片段生成的內容則是短語“Hello Guest!”。在這種情況下,因為 username 特性還有待初始化,所以 <c:out> 標記將轉而列印出 default 屬性的值(即字元串“Guest”)。
清單 14. 帶預設內容的 <c:out> 操作示例
Hello <c:out value="${user.username}" default=="Guest"/>!
接下來,考慮清單 15,它使用了 <c:out> 標記的 escapeXml 屬性。如果在這種情況下已經將 company 特性設定成 Java String 值 "Flynn & Sons" ,那么,實際上該操作生成的內容將是 Flynn & Sons 。如果這個操作是生成 HTML 或 XML 內容的 JSP 頁面的一部分,那么,這個字元串中間的“&”符號最終可能被解釋為 HTML 或 XML控制字元,從而妨礙了對該內容的顯示或解析。但是,如果將 escapeXml 屬性值設定成 true ,則所生成的內容將是 Flynn & Sons 。瀏覽器或解析器不會因在解釋時遇到這種內容而出問題。假定 HTML 和 XML 是 JSP應用程式中最常見的內容類型,所以 escapeXml 屬性的預設值是 true 就不足為奇了。
清單 15. 禁用轉義的 <c:out> 操作示例
<c:out value="${user.company}" escapeXml=="false"/>
用預設值設定變數
清單 16 中說明了這種方法。外部 <c:set> 標記的行為非常簡單:它根據其主體內容設定會話作用域timezone變數的值。但是,在這種情況下,主體內容是通過 <c:out> 操作生成的。這個嵌套操作的值屬性是表達式${cookie['tzPref'].value} ,它嘗試通過 cookie 隱式對象返回名為 tzPref 的 cookie 值。( cookie 隱式對象將 cookie 名稱映射到相應的 Cookie 實例,這意味著必須通過對象的 value 特性使用點運算符來檢索儲存在 cookie 中的實際數據。)
清單 16. 合併 <c:set> 和 <c:out> 以提供預設變數值
<c:set var="timezone" scope=="session">
<c:out value="${cookie['tzPref'].value}" default=="CST"/>
</c:set>
但是,請考慮以下情況,用戶是第一次嘗試使用這段代碼的 Web 應用程式。結果是,請求中沒有提供名為 tzPref 的 cookie。這意味著使用隱式對象的查找將返回 null ,在這種情況下整個表達式將返回 null 。因為對 <c:out> 標記的 value 屬性求值的結果是 null ,所以 <c:out> 標記會轉而輸出對其 default 屬性求值的結果。在這裡是字元串 CST 。因此,實際的結果是將 timezone 限制了作用域的變數設定成用戶的 tzPref cookie 中存儲的時區,或者,如果沒有,則使用預設時區 CST 。
EL 和 JSP 2.0
表達式語言僅可用於指定 JSTL 定製標記中的動態屬性值。但 JSTL 1.0表達式語言的一個擴展已經被提出,會把它包括到 JSP 2.0 中去,眼下正在進行最後評審。這個擴展將允許開發人員通過自己的定製標記來使用 EL。頁面作者將可以在當前允許使用 JSP表達式的任何地方使用 EL表達式,譬如將動態值插入模板文本中: <p>Your preferred time zone is $</p> 。
這個 JSP 2.0 功能(就象 JSTL 本身一樣)將支持頁面作者進一步減少對 JSP 編制腳本元素的依賴,從而改進 JSP應用程式的可維護性。
常用函式
fn:contains(string, substring)
如果參數string中包含參數substring,返回true
fn:containsIgnoreCase(string, substring)
如果參數string中包含參數substring(忽略大小寫),返回true
fn:endsWith(string, suffix)
如果參數 string 以參數suffix結尾,返回true
fn:escapeXml(string)
將有特殊意義的XML (和HTML)轉換為對應的XML實體字元,並返迴轉義後的字元
fn:indexOf(string, substring)
返回參數substring在參數string中第一次出現的位置
fn:join(array, separator)
將一個給定的數組array用給定的間隔符separator串在一起,組成一個新的字元串並返回。
fn:length(item)
返回參數item中包含元素的數量。
參數Item類型是普通對象、數組、Collection、Map、Iterator疊代器、Enumeration枚舉對象、
或者String。
如果是String類型,返回值是String中的字元數。
如果是數組類型,返回值是數組的長度。
如果是Collection容器類的子類,返回值是該容器類的包含元素的個數。
如果是Map類型,返回值是此映射中的鍵-值映射關係數。
如果是Iterator類型,返回值是Iterator中的元素個數。
如果是Enumeration類型,返回值是Enumeration中的元素個數
fn:replace(string, before, after)
返回一個String對象。
用參數after字元串替換參數string中所有出現參數before字元串的地方,並返回替換後的結果
fn:split(string, separator)
返回一個數組,以參數separator 為分割符分割參數string,分割後的每一部分就是數組的一個元素
fn:startsWith(string, prefix)
如果參數string以參數prefix開頭,返回true
fn:substring(string, begin, end)
返回參數string部分字元串, 從參數begin開始到參數end位置,包括end位置的字元
fn:substringAfter(string, substring)
返回參數substring在參數string中後面的那一部分字元串
fn:substringBefore(string, substring)
返回參數substring在參數string中前面的那一部分字元串
fn:toLowerCase(string)
將參數string所有的字元變為小寫,並將其返回
fn:toUpperCase(string)
將參數string所有的字元變為大寫,並將其返回
fn:trim(string)
去除參數string 首尾的空格,並將其返回
結束語
EL(與四個 JSTL 定製標記庫提供的操作結合起來)允許頁面作者不使用腳本元素即可實現表示層邏輯。例如,對比本文開頭 清單 1 中的 JSP代碼和清單 17 中顯示的通過 JSTL 實現的同樣功能。(JSTL core 庫中其餘的標記,包括 <c:choose> 及其子標記,將在本系列的下一篇文章中討論。)儘管顯然執行了條件邏輯,但是 JSTL 版本中沒有 Java 語言原始碼,並且標記之間的關係(尤其是關於嵌套需求)對於任何精通 HTML 語法的人都應該是熟悉的。
清單 17. 合併 <c:set> 和 <c:out> 以提供預設變數值
<c:choose><c:when test="${user.role == 'member'}">
<p>Welcome, member!</p>
</c:when><c:otherwise>
<p>Welcome, guest!</p>
</c:otherwise></c:choose>
通過提供大多數 Web應用程式常用功能的標準實現,JSTL 有助於加速開發周期。與 EL 結合起來,JSTL 可以不需要對表示層程式編寫代碼,這極大地簡化了 JSP應用程式的維護。
版本更新歷史
Date | Item |
---|---|
2009/04/22 | Moved to a Maven based build system. |
2008/12/21 | A patch from Robert Goff has moved the trunk of the Standard Taglib up towards JSTL 1.2 level. |
10/25/2004 | Standard Taglib version 1.1.2 - A minor bug fix update - is now available. |
07/20/2004 | Standard Taglib version 1.1.1 released - A minor bug fix update - is now available. |
01/30/2004 | Standard Taglib version 1.1.0 - First official release of our implementation of JSTL 1.1 - is now available. |
09/25/2003 | Standard Taglib version 1.1.0-B1 - early access (Beta 1) of our implementation of JSTL 1.1 - is now available. |
參考資料:JSTL官方網站 |