EL運算式的使用,EL運算式使用
在JSP 2.0的頁面中,我們使用下面形式的元素調用運算式語言:
${expression}
EL可以出現在JSP頁面的模板文本中,也可以出現在JSP標籤的屬性中。
下面是在JSP模板文本中使用運算式:
<ul>
<li>客戶名:${customer.custName}
<li>Email地址:${customer.email}
</ul>
下面是在JSP標準動作的屬性中使用EL運算式:
<jsp:include page = "${expression1}" />
<c:out value = "${expression2} " />
運算式語言的功能
(1)提供了一組簡單的運算子。運算式語言提供了一組簡單有效運算子,通過這些運算子可以完成算術、關係、邏輯、條件或空值檢查運算。
(2)對範圍變數的方便訪問。範圍變數是使用setAttribute()方法儲存在PageContext、HttpServletRequest、HttpSession或ServletContext範圍中的對象,可以簡單地使用下面的形式訪問:
${userName}
(3)對JavaBeans對象訪問的簡單表示。在JSP頁面中要訪問一個JavaBean對象customer的custName屬性,需要下面的文法:
<jsp:getProperty name="customer" property="custName">
而使用EL運算式,可以表示為:
${customer.custName}
(4)對集合元素的簡單訪問。集合包括數組、List對象、Map對象等,對這些對象的元素的訪問可以使用下面的簡單形式:
${variable[indexOrKey]}
(5)對請求參數、Cookie和其他請求資料的簡單訪問。如要訪問Accept要求標頭,可以使用header隱含變數,如下所示:
${header.Accept}或${header["Accept"]}
(6)提供了在EL中使用Java函數的功能。EL中不能定義和使用變數,也不能調用對象的方法,但可以通過標籤的形式使用Java語言定義的函數。
EL運算式和JSP的區別:
JSP運算式的使用格式為:
<%=expression %>
這裡的expression為合法的Java運算式,它屬於指令碼語言的代碼。在expression中可以使用由指令碼聲明的變數。
EL運算式的格式為:
${expression}
這裡的expression是符合EL規範的運算式,並且不需要包含在標籤內的。在EL運算式不能使用指令碼中聲明的變數。
使用傳統的指令碼語言,很容易在JSP中聲明變數,使用的標籤為<%!和%>,例如:
<%! int count = 100; %>
這裡聲明了一個整型變數,接下來使用下面的JSP運算式語句,這將輸出變數count的值為100:
The count value is :<%= count %>
而如果使用下面的語句,將返回一個空值,即用EL的empty運算子測試結果為true。
The count value is: ${count}
在EL中不能定義變數,也不能使用指令碼中聲明的變數,但它可以訪問請求參數、範圍變數、JavaBeans以及EL隱含變數等。
E算數運算子:
算術運算子 說明 示 例 結果
+ 加 ${6.80 + -12} -5.2
- 減 ${15-5} 10
* 乘 ${2 * 3.14159} 6.28318
/或div 除 ${25 div 5} 與 ${25/5} 5.0
%或mod 取餘 ${24 mod 5} 與 ${24 % 5} 4
在EL運算式中還可以使用“e”在浮點數中表示冪運算,例如:
${1.5e6/1000000} 的結果為 1.5;
${1e6 * 1} 的結果為 1000000.0。
這些操作在執行時調用類中的方法,但是要注意操作結果的資料類型。例如,定點數和浮點數的運算結果總是浮點數值。類似地,低精度的值與高精度的值進行運算,如一個Integer的值與一個BigInteger的值相加,總是得到一個高精度的值。
與數值一樣,String對象上也可以使用算術運算子,只要String對象能夠轉換為數值即可,例如:
${"16" * 4} 的結果為 64,字串被轉換成整數16;
${a div 4} 的結果為 0.0,a沒有定義,它的預設值為0;
${"a" div 4} 將產生編譯錯誤,字串“a”不能和數值運算。
關係運算子 說明 示 例 結果
== 或 eq 相等 ${3==5}或${3 eq 5} false
!= 或ne 不相等${3!=5}或${3 ne 5} true
< 或lt 小於${3<5}或${3 lt 5} true
> 或gt 大於${3>5}或${3 gt 5} false
<= 或le 小於等於${3<=5}或${3 le 5} true
>= 或ge 大於等於${3>=5}或${3 ge 5} false
在EL中不允許使用Java的流程式控制制語句,如if、for及while,因此,邏輯運算式的使用是直接顯示運算式的boolean值。
EL的條件運算子的文法是:
expression ? expression1 : expression2
運算式的值是基於expression的值,它是一個boolean運算式。如果expression的值為true,則返回expression1結果;如果expression的值為false,則返回expression2的結果。例如:
${(5 * 5) == 25 ? 1 : 0} 的結果為 1;
${(3 gt 2) && !(12 gt 6) ? "Right" : "Wrong"} 的結果為Wrong;
${("14" eq 14.0) && (14 le 16) ? "Yes" : "No"} 的結果為Yes;
${(4.0 ne 4) || (100 <= 10) ? 1 : 0} 的結果為 0。
empty運算子的使用格式為:
${empty expression}
它判斷expression的值是否為null、Null 字元串、空數組、空Map或空集合,若是則返回true,否則返回false。
屬性和幾何元素的訪問運算子
屬性訪問運算子用來訪問對象的成員,集合訪問運算子用來檢索Map、List或數組對象的元素。這些運算子在處理隱含變數時特別有用。在EL中,這類運算子有下面兩個:
• 點號(.)運算子。
• 方括弧([])運算子。
1. 點號(.)運算子
點號運算子用來訪問Map對象一個鍵的值或bean對象的屬性值,例如:param是EL的一個隱含對象,它是一個Map對象,下面代碼返回param對象username請求參數的值:
${param.username}
再比如,假設customer是CustomerBean類的一個執行個體,下面代碼訪問該執行個體的custName屬性值:
${customer.custName}
2. 方括弧([])運算子
方括弧運算子除了可以訪問Map對象鍵值和bean的屬性值外,還可以訪問List對象和數組對象的元素。例如:
${ param ["username"]}或${ param ['username']}
${customer["custName"]}
訪問範圍變數:
在JSP頁面中,可以使用JSP運算式訪問範圍變數。
一般做法是:在Servlet中使用setAttribute()方法將一個變數儲存到某個範圍對象上,如HttpServletRequest、HttpSession及ServletContext等。然後使用RequestDispatcher對象的forward()方法將請求轉寄到JSP頁面,在JSP頁面中調用隱含變數的getAttribute()方法返回範圍變數的值。
使用EL就可以更方便地訪問這些範圍變數。要輸出範圍變數的值,只需在EL中使用變數名即可,例如:
${variable_name}
對該運算式,容器將依次在頁面範圍、請求範圍、會話範圍和應用範圍中尋找名為variable_name的屬性。如果找到該屬性,則調用它的toString()方法並返回屬性值。如果沒有找到,則返回Null 字元串(不是null)。
訪問JavaaBean屬性:
設有一個名為com.model.CustomerBean的JavaBeans,它有一個名為custName的屬性。在JSP頁面中如果需要訪問custName屬性,應使用下面代碼實現:
<%@ page import="com.model.CustomerBean"%>
<%
CustomerBean customer= (CustomerBean)pageContext.findAttribute("customer");
customer.setCustName("Hacker");
%>
<%= customer.getCustName()%>
這裡使用了pageContext的findAttribute()方法尋找名為customer的屬性,使用JSP運算式輸出custName的值,但是如果找不到指定的屬性,上面的代碼會拋出NullPointerException異常。
如果知道JavaBeans的完整名稱和它的範圍,也可以使用下面JSP標準動作訪問JavaBeans的屬性:
<jsp:useBean id="customer" class="com.model.CustomerBean"
scope="session" />
<jsp:setProperty name="customer" property="custName" value="Hacker" />
<jsp:getProperty name="customer" property="custName" />
如果使用運算式語言,就可以通過點號標記法很方便地訪問JavaBeans的屬性,如下所示:
${customer.custName}
使用運算式語言,如果沒有找到指定的屬性不會拋出異常,而是返回Null 字元串。
使用運算式語言還允許訪問嵌套屬性。例如,如果CustomerBean有一個address屬性,它的類型為AddressBean,而AddressBean又有zipCode屬性,則可以使用下面簡單形式訪問zipCode屬性:
${customer.address.zipCode}
上面的方法不能使用<jsp:useBean>和<jsp:getProperty>實現。
下面通過一個樣本來說明對JavaBeans屬性的訪問。該例中有兩個JavaBeans,分別為AddressBean,它有三個字串類型的屬性,city、street和zipCode;CustomerBean是在前面的類的基礎上增加了一個AddressBean類型的屬性address表示地址。
在CustomerServlet.java程式中建立了一個CustomerBean對象並將其設定為請求範圍的一個屬性,然後將請求轉寄到JSP頁面,在JSP頁面中使用下面的EL訪問客戶地址的三個屬性:
<li>city:${customer.address.city}
<li>street: ${customer.address.street}
<li>zipCode:${customer.address.zipCode}
訪問集合元素:
在EL中可以訪問各種集合對象的元素,集合可以是數組、List對象或Map對象。這需要使用數組記法的運算子([])。例如,假設有一個上述類型的對象attributeName,可以使用下面形式訪問其元素:
${attributeName[entryName]}
如果attributeName對象是數組,則entryName為下標。上述運算式返回指定下標的元素值。
(1)下面代碼示範了訪問數組元素:
<%
String[] favoriteFruit = {"apple","orange","banana"};
request.setAttribute("favoriteList", favoriteFruit);
%>
My favorite fruit is:${favoriteList [2]}
上面一行還可以寫成:
My favorite fruit is:${favoriteList ["2"]}
(2)如果attributeName對象是實現了List介面的對象,則entryName為索引。
下面代碼示範了訪問List元素:
<%@ page import="java.util.ArrayList" %>
<%
ArrayList<String> favoriteFruit = new ArrayList<String>();
favoriteFruit.add("apple");
favoriteFruit.add("orange");
favoriteFruit.add("banana");
request.setAttribute("favoriteList", favoriteFruit);
%>
My favorite fruit is:${favoriteList [2]}
(3)如果attributeName對象是實現了Map介面的對象,則entryName為鍵,相應的值通過Map對象的get(key)方法獲得的,例如:
<%@ page import="java.util.*"
contentType="text/html;charset=gb2312" %>
<%
Map<String,String> capital = new HashMap<String,String>();
capital.put("England","倫敦");
capital.put ("China","北京");
capital.put ("Russia","莫斯科");
request.setAttribute("capital", capital);
%>
The capital of China is:${capital["China"]}
The capital of Russia is:${capital.Russia}
在EL中訪問隱含的變數:
在JSP頁面中可以訪問JSP隱含變數,如request、session、application等。在EL運算式中也定義了一套自己的隱含變數。使用EL可以直接存取這些隱含變數。
1. pageContext變數
pageContext是PageContext類型的變數。PageContext類依次擁有request、response、session、out和servletContext屬性,使用pageContext變數可以訪問這些屬性的屬性。
下面是一些例子:
${pageContext.request.method} //獲得HTTP請求的方法,如GET或POST。
${pageContext.request.queryString} //獲得請求的查詢串
${pageContext.request.requestURL} //獲得請求的URL
${pageContext.request.remoteAddr} //獲得請求的IP地址
${pageContext.session.id} //獲得會話的ID
${pageContext.session.new} //判斷會話對象是否是建立的
${pageContext.servletContext.serverInfo} //獲得伺服器的資訊
上述EL是通過成員訪問運算子訪問對象的屬性。在EL中不允許調用對象的方法,所以下面的使用是錯誤的:
${pageContext.request.getMethod()}
然而,仍然可以使用下面的指令碼運算式:
<%= request.getMethod() %>
2. param和paramValues變數
param和paramValues變數用來從ServletRequest中檢索請求參數值。param變數是調用給定參數名的getParameter(String name)方法的結果,使用EL表示如下:
${param.name}
類似地,paramValues是使用getParameterValues(String name)方法返回給定名稱的參數值的數組。要訪問參數值數組的第一個元素,可使用下面代碼:
${paramValues.name[0]}
上述代碼也可以用下面兩種形式表示:
${paramValues.name["0"]}
${paramValues.name['0']}
因為數組元素是按整數下標訪問的,因此必須使用“[]”運算子訪問數組元素。下面兩個運算式都會產生編譯錯誤:
${paramValues.name.0}
${paramValues.name."0"}
所以,EL在處理屬性和集合的訪問時與傳統的Java文法並不完全一樣。
3. header和headerValues變數
header和headerValues變數是從HTTP要求標頭中檢索值,它們的運行機制與param和paramValues類似。下面代碼使用EL顯示了要求標頭host的值。
${header.host}或${header["host"]}
類似地,headerValues.host是一個數組,它的第一個元素可使用下列運算式之一顯示:
${headerValues.host[0]}
${headerValues.host["0"]}
${headerValues.host['0']}
4. cookie變數
在Servlet中向客戶發送一個Cookie可以使用下面代碼:
Cookie cookie = new Cookie("userName","Hacker");
response.addCookie(cookie);
要檢索客戶發給伺服器的Cookie,應該使用下面代碼:
Cookie[] cookies = request.getCookies();
for(int i =0; i<cookies.length;i++){
if((cookies[i].getName()).equals("userName")){
out.println(cookies[i].getValue());
}
}
在JSP頁面中可以使用EL的cookie隱含變數得到客戶向伺服器發回的Cookie數組,即調用request對象的getCookies()方法的返回結果。如果要訪問cookie的值,則需要使用Cookie類的屬性value(即getValue方法)。因此,下面一行可以輸出名為userName的Cookie的值。如果沒有找到這個cookie對象,則輸出Null 字元串:
${cookie.userName.value}
使用cookie變數還可以訪問會話Cookie的ID值,例如:
${cookie.JSESSIONID.value}
5. initParam變數
initParam變數儲存了Servlet內容相關的參數名和參數值。例如,假設在DD中定義了如下初始化參數:
<context-param>
<param-name>email</param-name>
<param-value>hacker@163.com</param-value>
</context-param>
則可以使用下面的EL運算式得到參數email的值:
${initParam.email}
如果通過JSP指令碼元素訪問該Servlet上下文參數,應該使用下面運算式:
<%= application.getInitParameter("email") %>
6. pageScope、requestScope、sessionScope和applicationScope變數
這幾個隱含變數很容易理解,它們用來限定訪問不同範圍的屬性。例如,下面代碼在會話範圍中添加一個表示商品價格的totalPrice屬性,然後使用EL訪問該屬性值:
<%
session.setAttribute("totalPrice",1000);
%>
${sessionScope.totalPrice}
注意,訪問應用範圍的屬性應使用applicationScope變數而不是使用pageContext變數。
在EL中使用函數:
建立靜態方法:
在JSP頁面中使用EL函數需要建立下面三個檔案:
(1)方法的類檔案(*.java),它定義了在JSP中要使用的Java方法。
(2)標籤庫描述檔案(*.tld),它實現將每個Java方法與函數名的映射。
(3)JSP檔案(*.jsp),使用標籤庫URI以及函數名調用Java方法。
開發EL函數首先要建立在JSP中要調用的Java方法。在下面的例子中,建立了一個名為add(String x,String y)的方法來計算行程的兩個字串參數的和。
程式9.11 Compute.java
在建立EL函數時請記住下面這些要點:
(1)類需要聲明為public,方法需要聲明為public static。這樣容器可以不用建立新對象就可以訪問類的方法。
(2)類檔案要儲存在 /WEB-INF/classes目錄中。
(3)在EL中方法的參數和返回值必須合法。否則,Web容器將不能識別方法的簽名。
要在JSP頁面中調用這些方法還要建立一個標籤庫描述檔案。標籤庫描述檔案(Tag Library Descriptor,TLD)的主要作用是定義靜態方法與函數名之間的映射。
下面的TLD檔案就實現了add()方法與名為add的函數之間的映射。
程式9.12 sampleLib.tld
9.4.1 建立靜態(static)方法
9.4.3 在JSP中訪問EL函數
建立了TLD檔案後,在JSP中調用Java函數就非常簡單了,這主要包括兩步:
(1)通過taglib指令指定函數使用的首碼(prefix)和函數的URI,該URI必須與TLD檔案中定義的<uri>元素的值匹配。
(2)使用首碼名和函數名建立EL運算式。
程式9.13 sum.jsp
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。