java:EL表達式
EL表達式:
1)el表達式主要用於獲取數據,它的原理是:通知JSP引擎調用pageContext.findAttribute()方法,以標識符爲關鍵字從各個域中先後( page ——
request —— session —— application )獲取對象,如果在一個域中獲取到了,則不再從下個域中尋找,返回結果。如果域對象中不存在標識符所對應
的對象,則返回結果爲””(注意,不是null)。
2)EL表達式的四大作用:
>> 獲取數據(重點)
>> 執行運算
>> 獲取web開發對象
>> 調用java方法
3)可用page指令的isELIgnored屬性類控制頁面忽略所有的EL表達式,此時,所有的EL表達式都會被當成一個普通的字符串來處理:
<%@ page isELIgnored="false" %> // 默認爲false
1、EL作用之一:獲取數據
1)獲取四個域中的值:
a、
<%
pageContext.setAttribute("key", "el_page");
request.setAttribute("key", "el_request");
%>
key:${key}
<%-- 輸出結果爲:el_page --%>
b、
<c:set var="username" value="張三" scope="page" ></c:set>
username: ${username}
username: ${pageScope.username}
2)獲取存儲在四個域中的JavaBean對象的屬性值 ${beanName.屬性名 } :
舉例:
a、
<jsp:useBean id="student" class="cn.itcast.web.domain.Student" scope="page"/>
<jsp:setProperty name="student" property="name" value="張三" />
<jsp:setProperty name="student" property="age" value="30" />
<jsp:setProperty name="student" property="ID" value="24" />
<%-- 輸出結果爲:張三,30,24 --%>
姓名:${student.name}<br/>
年齡:${student.age}<br/>
ID:${student.ID}<br/>
注意:當使用EL表達式獲取javaBean的屬性的值時,前提是:這個對象必須是存進域中的,如果student對象時以普通方式創建,
即:Student student = new Student(24,"張三",30),則返回的結果爲””(空串)。因爲底層用的方式是:pageContext.findAttribute()
b、使用jstl設置javaBean的屬性,用EL表達式獲取(推薦):
<jsp:useBean id="student" class="cn.itcast.web.jsp.domain.Student" scope="request"></jsp:useBean>
<c:set target="${student}" property="name" value="張三" ></c:set>
<c:set target="${student}" property="age" value="15" ></c:set>
student.getName:${student.name}<br/>
student.getAge :${student.age}
3)在多個對象中導航的時候,如: ${XXX . YYY . ZZZ}
首先會調用pageContext.findAttribute(“XXX”)的方法,在四個域中尋找XXX的對象,接着是調用getYYY()的方法找到YYY對象,再調用getZZZ()
的方法得出結果,即:pageContext.findAttribute().getYYY().getZZZ()前提是:XXX、YYY對象也是存在與四個域中的!
${student.name.class.name}:
用意:pageContext.findAttribute("student").getName().getClass().getName();
但因爲pageContext.findAttribute("student").getName().getClass()返回的是:java.lang.String.class的對象,而這個對象並沒有存
在四個域中,而且經過驗證,無法將Class字節碼存入域對象:<jsp:useBean id="class" class="java.lang.Class" />
因爲id的值在此表示對象的引用變量,而class爲java中的保留關鍵字,所以無法用這種方式!!所以這樣做是錯誤的。
4)獲取數組、Collection、Map類型集合的數據(重點)
a、獲取List集合的元素
<%
List<String> strList = new ArrayList<String>();
strList.add("haha"); strList.add("hehe"); strList.add("xixi");
session.setAttribute("strList", strList); // 別忘了把集合綁定到域中
%>
第一個用戶:${strList[0]}<br/>
第二個用戶:${strList[1]}<br/>
第三個用戶:${strList[2]}<br/>
<c:forEach var="name" items="${strList}">
${name} <%-- haha hehe xixi --%>>
</c:forEach>
b、獲取Map集合的元素,注意Map集合的取出方式,調用的是entrySet的方法
<%
Map<String,Student> map = new HashMap<String,Student>();
Student s1 = new Student("A111","張三",12); Student s2 = new Student("B222","李四",12);
Student s3 = new Student("C333","王五",12);
map.put(s1.getId(), s1); map.put(s2.getId(), s2); map.put(s3.getId(), s3);
application.setAttribute("studentMap", map); // 別忘了把集合綁定到域中
%>
${studentMap}<br/>
<c:forEach var="entry" items="${studentMap} >
學生的編號:${entry.key}<br/>
學生的姓名:${entry.value}<br/>
</c:forEach>
c、獲取Set集合的元素
<%
Set<String> set = new HashSet<String>();
set.add("aaaaaaa");
set.add("bbbbbbb");
pageContext.setAttribute("set", set); // 別忘了把集合綁定到域中
%>
${set}<br/> <%-- [bbbbbbb, aaaaaaa] --%>
<c:forEach var="str" items="${set}">
${str}<br/>
</c:forEach>
d、獲取數組的元素
<%
int [] array = {1,2,3,4,5};
pageContext.setAttribute("array", array, PageContext.SESSION_SCOPE); // 別忘了把數組綁定到域中
%>
第二個值:${array[1]}<br/>
<c:forEach var="intValue" items="${array}">
${intValue}<br/>
</c:forEach>
2、EL作用之二:執行簡單的運算和邏輯判斷
示例:
${1==1}<br/> <%--true--%>
${5+4}<br/><%--9--%>
${student.age + 10}<br/><%--40--%>
${student.age > 20 && student.age < 50}<br/><%--true--%>
三種EL表達式中經常使用的運算符和一種表達式:
1、empty運算符 :檢查變量是否爲null或“空”,很好用!!!
2、二元表達式 :${user!=null?user.name : “”} ,很好用!!!
3、[ ] 和 . 號運算符
<c:set var="user" value="王五" scope="page" />
<c:remove var="user" scope="page" />
歡迎${!empty user ? user : "遊客"}光臨!!
<hr/>
數據回顯:
<c:set var="city" value="廣州" />
<select>
<option ${city == "廣州" ? "selected" : ""}>廣州</option>
<option ${city == "上海" ? "selected" : ""}>上海</option>
<option ${city == "北京" ? "selected" : ""}>北京</option>
</select>
3、EL表達式作用之三:獲取WEB開發常用對象
- EL表達式語言中定義了11個隱含對象,使用這些隱含對象可以很方便地獲取web開發中的一些常見對象,並讀取這些對象的數據。
- 語法:${隱式對象名稱}
<%--1、利用pageContext把當前的web應用路徑寫活: --%>
<a href="${pageContext.request.contextPath}/result.jsp" target="_blank">點擊</a>
<%--
底層用的方法就是:
HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
String contentPath = req.getContextPath();
--%>
<%--2、在指定的域中獲取綁定的對象 --%>
<c:set var="user" value="pageScope_user" scope="page" />
<c:set var="user" value="requestScope_user" scope="request"/>
<c:set var="user" value="sessionScope_user" scope="session"/>
<c:set var="user" value="applicationScope_user" scope="application"/>
用戶:${pageScope.user}<br/>
用戶:${requestScope.user}<br/>
用戶:${sessionScope.user}<br/>
用戶:${applicationScope.user}<br/>
<%--3、測試param與paramValues,地址欄訪問:
http://localhost:8080/jsp/el.jsp?sex=nan&like=basketball&like=football&like=swim --%>
性別:${param.sex}<br/>
<%--底層代碼:針對於一個參數
String sex = pageContext.getRequest().getParameter("sex");
--%>
第一個愛好:${paramValues.like[0]}<br/>
第二個愛好:${paramValues.like[1]}<br/>
第三個愛好:${paramValues.like[2]}<br/>
<%--底層代碼:針對多個同名參數
String [] like = pageContext.getRequest().getParameterValues("like");
--%>
<%--4、測試header與headerValues --%>
請求頭:${header}<br/>
請求頭:${header.host}<br/>
請求頭:${header.cookie}<br/>
請求頭:${headerValues['Accept-Encoding'][0]}<br/>
請求頭:${headerValues['Accept-Language'][0]}<br/>
<%--
測試headerValues時,如果頭裏面有“-” ,例Accept-Encoding,則
要headerValues[“Accept-Encoding”]
--%>
<%--5、測試cookie與initParam --%>
<%
Cookie cookie = new Cookie("password", "123456");
cookie.setMaxAge(24*60);
response.addCookie(cookie);
%>
cookie的名:${cookie.password.name}<br/>
cookie的值:${cookie.password.value}<br/>
<%--
測試cookie時,例${cookie.key}取的是cookie對象,如訪問cookie的名稱和值,須${cookie.username.name}或${cookie.username.value}。
new Cookie(“username”,”jack”);
--%>
web初始化參數:${initParam.tel}<br/>
web初始化參數:${initParam.email}<br/>
<%--
<context-param>
<param-name>tel</param-name>
<param-value>123</param-value>
</context-param>
<context-param>
<param-name>email</param-name>
<param-value>xxx@qq.com</param-value>
</context-param>
--%>
4、EL表達式作用之四:調用java方法
EL表達式語法允許開發人員開發自定義函數,以調用Java類的方法。
示例:${prefix:method(params)}
1)在EL表達式中調用的只能是Java類的靜態方法。
2)這個Java類的靜態方法需要在TLD文件中描述,纔可以被EL表達式調用。
3)EL自定義函數用於擴展EL表達式的功能,可以讓EL表達式完成普通Java程序代碼所能完成的功能。
4)EL函數只能訪問與WEB無關的需求,與WEB有關的需求還是需要使用自定義標籤來解決。
一般來說, EL自定義函數開發與應用包括以下三個步驟:
1)編寫一個Java類的靜態方法。
2)編寫標籤庫描述符(tld)文件,在tld文件中描述自定義函數,在WEB-INF/目錄下。
3)在JSP頁面中導入和使用自定義函數。
1) 寫一個普通類,在其中寫一個靜態的方法
public class Filter {
// 轉義方法
public static String filter(String message) {
return null;
}
}
2)tld文件的配置:
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web- jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>el</short-name> // 函數的前綴
<uri>http://java.sun.com/jsp/jstl/el</uri>
<function>
<name>filter</name>
<function-class>cn.itcast.web.jsp.el.Filter</function-class>
<function-signature>java.lang.String filter(java.lang.String)</function-signature>
</function>
</taglib>
3)在JSP頁面中引用自定義EL函數
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/el" prefix="el" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
${el:filter("<a href='#'>點點</a>")}<br/>
</body>
</html>
開發EL Function注意事項:
1)編寫完標籤庫描述文件後,需要將它放置到<web應用>\WEB-INF目錄中或WEB-INF目錄下的除了classes和lib目錄之外的任意子目錄中。
2)TLD文件中的<uri> 元素用指定該TLD文件的URI,在JSP文件中需要通過這個URI來引入該標籤庫描述文件。
<function>元素用於描述一個EL自定義函數,其中:
<name>子元素用於指定EL自定義函數的名稱。
<function-class>子元素用於指定完整的Java類名。
<function-signature>子元素用於指定Java類中的靜態方法的簽名,方法簽名必須指明方法的返回值類型及各個參數的完整類型,
各個參數之間用逗號分隔。
EL注意事項:
EL表達式是JSP 2.0規範中的一門技術 。因此,若想正確解析EL表達式,需使用支持Servlet2.4/JSP2.0技術的WEB服務器。
注意:有些Tomcat服務器如不能使用EL表達式
1)升級成tomcat6/7
2)升級JSTL的JAR包
3)在JSP中加入<%@ page isELIgnored="false" %> 即,告訴JSP引擎不忽略EL表達式語言。
4)struts中不推薦使用EL表達式,而struts使用的是OGNL(對象導航語言)