在 JSP 頁面中,使用標籤庫代替傳統的 Java 片段語言來實現頁面的顯示邏輯已經不是新技術了,然而,由自定義標籤很容易造成重複定義和非標準的實現。鑑於此,出現了 JSTL ( JSP Standard Tag Library )。大多數 JSP 頁面邏輯提供了實現的 JSTL 技術,該技術本身就是一個標籤庫。
Sun 公司 Java 規範標準的 JSTL 由 apache jakarta 組織負責維護。作爲開源的標準技術,它一直在不斷地完善。 JSTL 的發佈包有兩個版本: Standard-1.0 Taglib 、 Standard-1.1 Taglib ,它們在使用時是不同的。
q Standard-1.0 Taglib ( JSTL1.0 )支持 Servlet2.3 和 JSP1.2 規範, Web 應用服務器 Tomcat4 支持這些規範,而它的發佈也在 Tomcat 4.1.24 測試通過了。
q Standard-1.1 Taglib ( JSTL1.1 )支持 Servlet2.4 和 JSP2.0 規範, Web 應用服務器 Tomcat5 支持這些規範,它的發佈在 Tomcat 5.0.3 測試通過了。
在本章的介紹中,將以由 Sun 發佈的 Standard-1.1 Taglib 標籤庫爲主,而 apache jakarta 組織發佈的開源標籤庫,可以從 http://jakarta.apache.org/taglibs/ 找到所需要的幫助。 Sun 發佈的標準 JSTL1.1 標籤庫有以下幾個標籤:
q 核心標籤庫:包含 Web 應用的常見工作,比如:循環、表達式賦值、基本輸入輸出等。
q 國際化標籤庫:用來格式化顯示數據的工作,比如:對不同區域的日期格式化等。
q 數據庫標籤庫:可以做訪問數據庫的工作。
q XML 標籤庫:用來訪問 XML 文件的工作,這是 JSTL 標籤庫的一個特點。
q 函數標籤庫:用來讀取已經定義的某個函數。
此外,
JSTL
還提供了
EL 表達式語言(
Expression Language
)來進行輔助的工作。
JSTL 標籤 庫由標籤庫和 EL 表達式語言兩個部分組成。 EL 在 JSTL 1.0 規範中被引入,當時用來作爲 Java 表達式來工作,而該表達式必須配合 JSTL 的標籤庫才能得到需要的結果。
說明:在 JSTL 1.1 規範中, JSP2.0 容器已經能夠獨立的理解任何 EL 表達式。 EL 可以獨立出現在 JSP 頁面的任何角落。本文隨後的內容將以 JSTL 1.1 規範作爲介紹的重點。
一 JSTL EL表達式語言簡介
EL 是從 JavaScript 腳本語言得到啓發的一種表達式語言,它借鑑了 JavaScript 多類型轉換無關性的特點。在使用 EL 從 scope 中得到參數時可以自動轉換類型,因此對於類型的限制更加寬鬆。 Web 服務器對於 request 請求參數通常會以 String 類型來發送,在得到時使用的 Java 語言腳本就應該是 request.getParameter(“XXX”) ,這樣的話,對於實際應用還必須進行強制類型轉換。而 EL 就將用戶從這種類型轉換的繁瑣工作脫離出來,允許用戶直接使用 EL 表達式取得的值,而不用關心它是什麼類型。
下面的示例就是一個 EL 表達式,見例 1 。
例 1 :簡單 EL 表達式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
${sampleValue + 1} <br>
</body>
</html>
這個示例將在 JSP 頁面顯示爲“ 1 ”, EL 表達式必須以“ ${XXX} ”來表示,其中“ XXX ”部分就是具體表達式內容,“ ${} ”將這個表達式內容包含在其中作爲 EL 表達式的定義。本示例可以在滿足 JSP2.0 規範的任何 Web 應用服務器中使用。
二 EL表達式的默認變量
一個 EL 表達式包含變量和操作符兩個內容。任何存在於 JSP 作用範圍的 JavaBean 都可以被轉化成 EL 表達式來使用,它所包含的默認變量如下:
1 .默認變量 pageScope 、 requestScope 、 sessionScope 、 applicationScope
這 4 個默認變量包含 Scope 作用範圍的參數集合,相當於被保存在 java.util.Map 中的某個參數。下面看簡單的示例 2 :
例 2 :使用 sessionScope 變量的 EL 表達式
${sessionScope.sampleValue}
取得保存在 Session 中參數的 sessionScope 變量的 EL 表達式,“ . ”是 property 訪問操作符,在這裏表示從 Session 中取得“鍵”爲“ sampleValue ”的參數,並顯示出來。顯示結果爲“ 10 ”。
2 .默認變量 param 、 paramValues
這兩個默認變量包含請求參數的集合, param 表明請求包含的參數爲單一控件, paramValues 表明請求包含的參數爲控件數組。下面看一個簡單示例 3 :
例
3
:提交請求的頁面和接受的頁面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
<form action="SampleJsp.jsp">
<input type="text" name="sampleValue" value="10">
<input type="text" name="sampleValue" value="11">
<input type="text" name="sampleValue" value="12">
<input type="text" name="sampleSingleValue" value="SingleValue">
<input type="submit" value="Submit">
</form>
</body>
</html>
在這個頁面中定義了兩組控件,控件名爲“ sampleValue ”的是一套控件數組,控件名爲“ sampleSingleValue ”的是單一控件,通過遞交將請求參數傳送到 SampleJsp.jsp 。
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<body>
${paramValues.sampleValue[2]} <br>
${param.sampleSingleValue} <br>
</body>
</html>
這是請求轉發到的頁面,通過 EL 表達式的 paramValues 變量得到控件數組中最後一個控件的遞交參數,通過 EL 表達式的 param 變量得到單一控件的遞交參數。控件數組參數的 EL 表達式使用“ [] ”來指定數組下標。本示例將顯示控件數組中最後一個控件的值“ 12 ”和單一控件的值“ SingleValue ”。
3 .默認變量 header 、 headerValues
這兩個默認變量包含請求參數頭部信息的集合, header 變量表示單一頭部信息, headerValues 則表示數組型的頭部信息。
4 .默認變量 cookie
包含所有請求的 cookie 集合,集合中的每個對象對應 javax.servlet.http.Cookie 。
5 .默認變量 initParam
包含所有應用程序初始化參數的集合。
6 .默認變量 pageContext
等價於 page 環境類 javax.servlet.jsp.PageContext 的實例,用來提供訪問不同的請求參數。
11 個默認變量幾乎包含了 Web 應用的所有基本操作,若一個表達式不使用這些變量而直接使用參數名,那麼就採用就近原則。該表達式將使用最近取得的參數值。
三.EL表達式的操作符
EL表達式中還有許多操作符可以幫助完成各種所需的操作,之前的示例中“.”、“[]”就是其中的兩個,下面將用表9.1來展示所有操作符及它們各自的功能。
表 9.1 EL 表達式的操作符
操作符 |
功能和作用 |
. |
訪問一個 bean 屬性或者 Map entry |
[] |
訪問一個數組或者鏈表元素 |
() |
對子表達式分組,用來改變賦值順序 |
? : |
條件語句,比如:條件 ?ifTrue:ifFalse 如果條件爲真,表達式值爲前者,反之爲後者 |
+ |
數學運算符,加操作 |
- |
數學運算符,減操作或者對一個值取反 |
* |
數學運算符,乘操作 |
/ 或 div |
數學運算符,除操作 |
% 或 mod |
數學運算符,模操作 ( 取餘 ) |
== 或 eq |
邏輯運算符,判斷符號左右兩端是否相等,如果相等返回 true ,否則返回 false |
!= 或 ne |
邏輯運算符,判斷符號左右兩端是否不相等,如果不相等返回 true ,否則返回 false |
< 或 lt |
邏輯運算符,判斷符號左邊是否小於右邊,如果小於返回 true ,否則返回 false |
> 或 gt |
邏輯運算符,判斷符號左邊是否大於右邊,如果大於返回 true ,否則返回 false |
<= 或 le |
邏輯運算符,判斷符號左邊是否小於或者等於右邊,如果小於或者等於返回 true ,否則返回 false |
>= 或 ge |
邏輯運算符,判斷符號左邊是否大於或者等於右邊,如果大於或者等於返回 true ,否則返回 false |
&& 或 and |
邏輯運算符,與操作賦。如果左右兩邊同爲 true 返回 true ,否則返回 false |
|| 或 or |
邏輯運算符,或操作賦。如果左右兩邊有任何一邊爲 true 返回 true ,否則返回 false |
! 或 not |
邏輯運算符,非操作賦。如果對 true 取運算返回 false ,否則返回 true |
empty |
用來對一個空變量值進行判斷 : null 、一個空 String 、空數組、 空 Map 、沒有條目的 Collection 集合 |
func(args) |
調用方法 , func 是方法名, args 是參數,可以沒有,或者有一個、多個參數 . 參數間用逗號隔開 |
這些操作符都是極其有用的,下面通過幾個示例來演示它們的使用方法:
例 4 :幾組操作符的示例
${(pageScope.sampleValue + 12)/3} <br> // 顯示 4.0
${(pageScope.sampleValue + 12) /3==4} <br> // 顯示 true
${(pageScope.sampleValue + 12) /3>=5} <br> // 顯示 false
<input type="text" name="sample1" value="${pageScope.sampleValue + 10}"> // 顯示值爲 10 的 Text 控件
可以看到,對於這些示例,程序設計者完全無需管理它們的類型轉換,在表達式內部都已經處理了。有了 EL 表達式,在 JSP 頁面的編程變得更靈活,也更容易。
1.普通字符串
request.setAttribute("hello", "hello world");
---------------------------------------------El表達式獲取
<li>普通字符串</li><br>
hello(jsp腳本):<%=request.getAttribute("hello") %><br>
hello(el表達式,el表達式的使用方法$和{}):${hello }<br>
hello(el表達式,el的隱含對象pageScope,requestScope,sessionScope,applicationScope,
<br> 如果未指定scope,它的搜索順序pageScope~applicationScope):${requestScope.hello }<br>
hello(el表達式,scope=session):${sessionScope.hello }<br>
--------------------------------------------頁面輸出
.普通字符串
hello(jsp腳本):hello world
hello(el表達式,el表達式的使用方法$和{}):hello world
hello(el表達式,el的隱含對象pageScope,requestScope,sessionScope,applicationScope,
如果未指定scope,它的搜索順序爲pageScope~applicationScope):hello world
hello(el表達式,scope=session):
<><><><><><><><><><><><><><><><><><><>
2.結構
Group group = new Group();
group.setName("尚學堂");
User user = new User();
user.setUsername("張三");
user.setAge(18);
user.setGroup(group);
request.setAttribute("user", user);
---------------------------------------------El表達式獲取
<li>結構,採用.進行導航,也稱存取器</li><br>
姓名:${user.username }<br>
年齡:${user.age }<br>
所屬組:${user.group.name }<br>
注意:如果想通過el表達式調用bean中的方法,要寫一個get開頭並且參數爲空的函數纔可以調用:
原來的方法:
public boolean checkUsername(request){...}
修改之後:
public boolean checkUsername(request){...}
public boolean getCheckUsername(){
request = ...;
return checkUsername(request);
}
--------------------------------------------頁面輸出
.結構,採用.進行導航,也稱存取器
姓名:張三
年齡:18
所屬組:尚學堂
<><><><><><><><><><><><><><><><><><><>
3.map
Map mapValue = new HashMap();
mapValue.put("key1", "value1");
mapValue.put("key2", "value2");
request.setAttribute("mapvalue", mapValue);
---------------------------------------------El表達式獲取
<li>輸出map,採用.進行導航,也稱存取器</li><br>
mapvalue.key1:${mapvalue.key1 }<br>
mapvalue.key2:${mapvalue.key2 }<br>
--------------------------------------------頁面輸出
.輸出map,採用.進行導航,也稱存取器
mapvalue.key1:value1
mapvalue.key2:value2
<><><><><><><><><><><><><><><><><><><>
4.字符串數組
String[] strArray = new String[]{"a", "b", "c"};
request.setAttribute("strarray", strArray);
User[] users = new User[10];
for (int i=0; i<10; i++) {
User u = new User();
u.setUsername("U_" + i);
users[i] = u;
}
request.setAttribute("users", users);
---------------------------------------------El表達式獲取
<li>輸出對象數組,採用[]和下標</li><br>
userarray[3].username:${users[2].username }<br>
--------------------------------------------頁面輸出
.輸出對象數組,採用[]和下標
userarray[3].username:U_2
<><><><><><><><><><><><><><><><><><><>
5.ArrayList
List userList = new ArrayList();
for (int i=0; i<10; i++) {
User uu = new User();
uu.setUsername("UU_" + i);
userList.add(uu);
}
request.setAttribute("userlist", userList);
---------------------------------------------El表達式獲取
<li>輸出list,採用[]和下標</li><br>
userlist[5].username:${userlist[4].username }<br>
--------------------------------------------頁面輸出
輸出list,採用[]和下標
userlist[5].username:UU_4
<><><><><><><><><><><><><><><><><><><>
6.empty
request.setAttribute("value1", null);
request.setAttribute("value2", "");
request.setAttribute("value3", new ArrayList());
request.setAttribute("value4", "123456");
---------------------------------------------El表達式獲取
<li>el表達式對運算符的支持</li><br>
1+2=${1+2 }<br>
10/5=${10/5 }<br>
10 div 5=${10 div 5 }<br>
10%3=${10 % 3 }<br>
10 mod 3=${10 mod 3 }<br>
EL調用bean中的方法:
- public boolean getCheckUser();
- HttpServlet request = threadLocal.getRequest;
- return CheckUser(request );
- }
首先,把request放到某個能隨時取得的地方,如ThreadLocal裏面,然後,寫一個方法,沒有參數,在這個方法中調用你原先的方法,最後,在頁面上寫:
<c:when test= "${XmlUser.checkUser} ">