第二十九章:EL表示式
作者:java_wxid
什麼是EL表示式?
E L的全稱:Expression Language,就是表示式語言。可以輸出表達式的值。跟jsp的表示式指令碼一樣。計算表示式的值後輸出。 EL表示式出現的目的是為了使JSP寫起來更加簡單,讓jsp的程式碼更佳簡化。
我們先來看一下EL表示式的一個Hello world 程式,看看它是如何簡化jsp程式碼。
EL 表示式的Hello world 程式!!!
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% //首先我們需要在request域物件中設定一個屬性 request.setAttribute("hello", "這是內容"); %> <%-- 獲取請求域中的屬性hello輸出 --%> jsp的輸出:<%=request.getAttribute("hello") == null ? "" : request.getAttribute("hello")%><br/><br/> <%-- 輸出在域中查詢輸出hello的值 --%> EL表示式的輸出:${hello}<br/><br/> </body> </html>
從上面的程式,我們不難看出。我們要輸出域中的屬性,方便多了。
所以el表示式使得jsp頁面的程式碼變得更加簡潔。主要用於替換 jsp 中表達式指令碼。
EL表示式的最主要功能就是從域物件中獲取資料,並且輸出
EL表示式,獲取域物件資料(*****重點)
使用EL表示式獲取資料的語法: “${識別符號}”
第一點:當EL表示式輸出的key不存在的時候,輸出的是空串””
第二點:EL表示式在域物件中搜索屬性的順序是搜尋四個域物件的順序 是從小到大,pageContext=====>>>> request=====>>>>session=====>>>>application
EL表示式可以從域物件中獲取資料
1、EL表示式獲取域資料的順序
EL 表示式語句在執行時,會用識別符號為關鍵字分別從page、request、session、application四個域中查詢對應key的物件。
找到則返回相應資料。找不到則返回空串。(注意,不是null,而是空字串)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% //我們在四個域物件中設定同一個屬性 pageContext.setAttribute("hello", "page這是內容"); request.setAttribute("hello", "request這是內容"); session.setAttribute("hello", "session這是內容"); application.setAttribute("hello", "application這是內容"); %> <%-- 從page,request,session,application四個作用域中順序查詢對應的key的值輸出,如果沒有找到就輸出空串 --%> ${hello}<br/> </body> </html>
測試步驟:
1.寫好頁面程式碼,直接訪問頁面,輸出pageContext中的內容。
2.注掉pageContext.setAttribute 程式碼。重新整理頁面,輸出request域範圍的hello屬性值。
3.注掉 request.setAttribute 程式碼。重新整理頁面,輸出Session域範圍的hello屬性值。
4.注掉 session.setAttribute 程式碼,並且關閉瀏覽器後重新開啟瀏覽器訪問頁面。輸出 application(ServletContext)域範圍的屬性值
5.注掉application.setAttribute程式碼,關閉伺服器。然後再啟動伺服器。再開啟瀏覽器,再訪問頁面。application中也沒有資料了
2、獲取javaBean普通屬性、陣列屬性、List集合屬性,以map屬性中的資料。
例如:
${ user.username } // 獲取user物件中。username屬性值
${ list[下標] } // 訪問有序集合(或陣列)中給定索引的元素
${ map.key } // 訪問map集合中指定key的屬性值
${ map[“key”] } // 訪問特殊字串的key的屬性值
注意:[] 中括號 除了可以訪問帶有順序的集合和陣列的元素之外。
還可以訪問特殊的key值
需求:建立一個User類物件,新增字串屬性,陣列屬性,List集合屬性。map屬性。
然後建立一個物件例項新增到request域物件中測試獲取
一定要記住一點,EL表示式獲取資料的時候,是通過對應的get方法獲取的
BeanUtils 是通過set方法設定值
a) 先定義一個JavaBean物件------User類
public class User {
private String username;
private String[] phones;
private Map<String, Object> map;
private List<String> strList;
b) 在jsp頁面中新增一些物件到四個域物件中,使用el表示式訪問測試。
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="java.util.HashMap"%>
<%@page import="com.atguigu.servlet.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// 建立一個map物件,並新增資料
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("aaa", "AAAValue");
map.put("bbb", "bbbValue");
map.put("ccc", "cccValue");
map.put("ddd", "dddValue");
// 建立一個list集合物件
List<String> strList = new ArrayList<String>();
strList.add("aaa");
strList.add("bbb");
strList.add("ccc");
// 建立一個User物件
User user = new User("使用者名稱",new String[]{"第一個電話","第二個電話","第三個電話"},map,strList);
// 把使用者物件新增到請求request的屬性中
request.setAttribute("user", user);
%>
<%--訪問 物件的username 屬性--%>
user物件的username屬性值---->>>>${ user.username }<br/><br/>
<%--訪問user物件中陣列的第二個元素--%>
user物件中phones陣列的第二個元素-------->>>>${ user.phones[1] }<br/><br/>
<%--訪問 list集合 中第一個元素--%>
list集合中第一個元素-------->>>>>${ user.strList[0] }<br/> <br/>
<%--訪問 user物件中map集合的aaa的屬性值 --%>
user物件中map集合中aaa屬性的值----->>>>>${ user.map.aaa }<br/><br/>
</body>
</html>
頁面輸出如下:
注意:去掉多餘的程式碼驗證
EL 表示式–運算。
語法:${ 運算表示式 } , EL 表示式支援如下運算子:
1)關係運算
2)邏輯運算
3)算數運算
4)empty運算子(***常用)
empty 運算可以判斷el表示式的某個key的值是否為空,如果為空返回true,反之就返回false。
1、值為null的時候。返回true
2、值為空串的時候,返回true
3、值為Object陣列時,並且長度為零,返回true
4、值為list集合,然後元素個數為零,返回true
5、值為map集合,然後元素個數為零,返回true
empty運算測試程式碼:
<%@page import="java.util.Map"%>
<%@page import="java.util.List"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// 物件為null時,返回true
request.setAttribute("nullObject", null);
//如果是空的字串,返回true
request.setAttribute("emptyStr", "");
//如果是空的陣列,返回true
request.setAttribute("emptyArr", new Object[]{});
//空的集合,返回true
List list = new ArrayList();
request.setAttribute("emptyList", list);
//空的map,返回true
Map map = new HashMap();
request.setAttribute("emptyMap", map);
%>
<h1>EL empty 運算</h1>
物件為null,empty為真 ---->>>>${ empty nullObject }<br/>
空的字串,empty為真------>>>>${ empty emptyStr }<br/>
空的陣列,empty為真------>>>>${ empty emptyArr }<br/>
空的list集合,empty為真---->>>>${ empty emptyList }<br/>
空的map集合,empty為真----->>>>${ empty emptyMap }<br/>
</body>
</html>
瀏覽器執行結果:
5)三元運算
我們可以在EL 表示式中方便的使用三元運算輸出。
語法:${ 表示式1 ? 表示式2 : 表示式3 }
示例:${ 12 == 12 ? "12 等於 12" : "12 != 12" }
我們可以很方便的在EL 表示式中使用三元運算子進行運算。
${ 表示式1 ? 表示式2:表示式3 }
當表示式1值為真時,EL輸出表達式2的值
當表示式1值為假時,EL輸出表達式3的值
6)“.” 點 和 [] 中括號 運算子
“.” 運算子,可以取JavaBean物件的屬性值,也可以取map中某個key的值。
[] 中括號,可以獲取有序集合中指定索引的元素,也可以獲取特殊key的值。
當我們在map物件中存放一些特殊的key的時候。
比如說。key字串中含有 “.” 、“+” 、“-” 、“*” 、“/” 、 “%” 等 這些運算子的時候。
會讓el解析器產生歧義的時候。我們可以使用[‘key’]中括號加引號包含key的形式取值。
[] 中括號,不僅可以獲取有序集合(陣列和List集合)中的給定索引的元素,
還可以獲取key中含有特殊意義字元的key對應的值。
比如key中含有 “.” , “+” , “_” , “*” , “/” 等的運算字元
示例:
<body>
<%
//設定
Map map = new HashMap();
map.put("a-b-c","a-b-c-Value");
map.put("a.b.c", "a.b.c.Value");
map.put("aaa","aaa-Value");
request.setAttribute("map", map);
%>
<%-- 下面我們可以通過中括號方式獲取對應key的值 --%>
${ map['a.b.c'] }<br/>
${ map['a-b-c'] }<br/>
${ map.aaa }<br/>
</body>
輸出為:
a.b.c.Value
a-b-c-Value
aaa-Value
EL表示式中11個隱含物件。
EL表示式 中隱含11個物件,這11個物件我們都可以直接使用!!!
EL表示式獲取域物件中的資料(****重點)
pageScope <=== 對應 ===> pageContext 域中的屬性
requestScope <=== 對應 ===> request 域中的屬性
sessionScope <=== 對應 ===> session 域中的屬性
applicationScope <=== 對應 ===> ServletContext 域中的屬性
我們先來看一下。如何從四個域物件中。獲取各自的屬性
需求:分別往四個域物件中儲存資料,然後使用pageScope,requestScope,sessionScope,applicationScope中取出資料
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// 在四個域中存放資料,進行獲取
pageContext.setAttribute("key", "pageContext-value");
request.setAttribute("key", "request-Value");
session.setAttribute("key", "session-value");
application.setAttribute("key", "application-value");
%>
<%-- 從不同的域中獲取資料 --%>
page域中key的值:${ pageScope.key }<br/>
request域中key的值:${ requestScope.key }<br/>
session域中key的值:${ sessionScope.key }<br/>
application域中key的值:${ applicationScope.key }<br/>
</body>
</html>
執行的結果:
pageContext訪問Jsp中內建物件(用的不多)。
通過pageContext物件。我們可以直接獲取jsp中的一些內建物件,
比如:
request物件,
session物件,
Servletconfig物件,
ServletContext物件,
然後獲取一些我們需要的資訊。
常用的功能獲取
協議:
伺服器ip:
伺服器埠:
獲取工程路徑:
獲取請求方法:
獲取客戶端ip地址:
獲取會話的id編號:
pageContext使用示例程式碼
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
協議:${ pageContext.request.scheme }<br/>
伺服器ip:${ pageContext.request.serverName }<br/>
伺服器埠:${ pageContext.request.serverPort }<br/>
獲取工程路徑:${ pageContext.request.contextPath }<br/>
獲取請求方法:${ pageContext.request.method }<br/>
獲取客戶端ip地址:${ pageContext.request.remoteHost }<br/>
獲取會話的id編號:${ pageContext.session.id }<br/>
</body>
</html>
pageContext物件最常用的功能就是獲取上下文路徑(也就是工程路徑名)
工程名(上下文路徑):\${ pageContext.request.contextPath }
但是在實際專案中。為了縮短程式碼量,會把request物件放在pageContext域物件中。然後再使用,比如說
<%
// 先把request物件放到pageContext域物件中
pageContext.setAttribute(“req”,request);
%>
然後EL表示式程式碼改為
工程名(上下文路徑):\${ req.contextPath }
EL表示式其他隱含物件的使用。
web.xml檔案中的配置內容:
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
使用的示例程式碼:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
引數username的值:${ param.username }<br/>
引數hobby的值:${ paramValues.hobby[0] }<br/>
請求頭Accept-Language的值:${ header["Accept-Language"] }<br/>
請求頭Accept的值:${ headerValues["Accept"][0] }<br/>
cookie的key = ${ cookie.JSESSIONID.name } : value = ${ cookie.JSESSIONID.value } <br/>
上下文引數:${ initParam.username }<br/>
</body>
</html>
訪問的顯示結果: