注意
這里詳細(xì)講解如何在jsp中使用el表達(dá)式,。
如果你不滿足以下任一條件,,請繼續(xù)閱讀,否則請?zhí)^此后的部分,,進(jìn)入下一章:第 14 章 生命周期,。
-
了解如何在jsp中使用及禁用el表達(dá)式。
-
了解el表達(dá)式的取值方式,。
13.1. 再談el(Expression Language)
我們已經(jīng)知道el是jsp-2.0規(guī)范的一部分,,tomcat-5.x版本以上都已經(jīng)能夠支持jsp-2.0規(guī)范,,但在更低版本的tomcat和webphere,weblogic中還是無法使用這一便捷方式。
其實我們也可以選擇在jsp中禁止使用el表達(dá)式,,使用jsp指令(directive)可以對禁用某一個jsp中的el表達(dá)式,。
禁用之后的el表達(dá)式會以原樣顯示出來,如下圖所示,。
為了對照,,我們還在13-01下放了一個可以正常使用el表達(dá)式的例子,運(yùn)行效果如下圖顯示,。
在13-01/index.jsp中禁用el表達(dá)式,,是使用了isELIgnore="true"這樣一條jsp指令(directive),請注意大小寫,。
<%@ page isELIgnored="true" %>
<%
pageContext.setAttribute("hello", "Hello World");
%>
${hello}
還有一種批量禁用el的方法,,我們可以在WEB-INF/web.xml中使用jsp-property-group標(biāo)簽批量禁用el,我們在13-02/WEB-INF/web.xml中進(jìn)行如下配置,。
<xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java./xml/ns/j2ee"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xsi:schemaLocation="http://java./xml/ns/j2ee http://java./xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
</web-app>
這樣就會禁用所有以.jsp后綴的請求中的el表達(dá)式,,使用這種方式需要注意兩點(diǎn)。
-
jsp-property-group標(biāo)簽是jsp-2.0中新增功能,,如果你使用低版本的web.xml(2.3或以下)就不能使用這個標(biāo)簽了,。
-
設(shè)置jsp-config會影響jsp生成servlet的過程,如果程序修改時已經(jīng)有jsp轉(zhuǎn)換成servlet并緩存在work目錄下,,那么修改后需要先清除緩存,,才能看到效果,。
實際上還有第三種方法可以禁用掉所有jsp中的el表達(dá)式,,那就是把web.xml定義為2.3版。
<xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java./dtd/web-app_2_3.dtd">
<web-app>
</web-app>
這個就是13-03/WEB-INF/web.xml的定義,,定義了web-app的版本號是2.3,,這樣一來所有的jsp都無法使用el表達(dá)式了,因為el表達(dá)式是2.4版才開始支持的功能,。
注意
說了以上三種禁用el表達(dá)式的方法,,不是希望大家拋棄el表達(dá)式,相反是希望大家在自己編寫el時出現(xiàn)問題時,,先去考慮是否有人在這三個地方做了設(shè)置造成el表達(dá)式的失效,。建議大家多多使用el表達(dá)式,少用一些jsp中的scriptlet代碼,。
使用el的時候,,默認(rèn)會以一定順序搜索四個作用域,將最先找到的變量值顯示出來,。
如果我們有${username}這樣一個正則表達(dá)式,,它回去依次調(diào)用pageContext.getAttribute("username") -> request.getAttribute("username") -> session.getAttribute("username") -> application.getAttribute("username"),,只要找到某一個不為空的值就立刻返回。
這樣的確方便我們的操作,,但是隨之也出現(xiàn)了另外一個問題,,如果pageContext和request中有同名變量,但是我想取得request中的變量該如何是好呢,?這就需要為el表達(dá)式引入作用域的概念了,。
${pageScope.username}
${requestScope.username}
我們可以直接訪問13-04這個應(yīng)用,看看el表達(dá)式支持的所有對象,。
下面我們分別對每個作用域?qū)ο筮M(jìn)行講解,。
表 13.1. el中的作用域
el中的作用域 |
對應(yīng)關(guān)系 |
pageContext(1) |
當(dāng)前頁的pageContext對象 |
pageScope |
把page作用域中的數(shù)據(jù)映射為一個map對象 |
requestScope(2) |
把request作用域中的數(shù)據(jù)映射為一個map對象 |
sessionScope |
把session作用域中的數(shù)據(jù)映射為一個map對象 |
applicationScope |
把a(bǔ)pplication作用域中的數(shù)據(jù)映射為一個map對象 |
param |
對應(yīng)request.getParameter() |
paramValues(3) |
對應(yīng)request.getParameterValues() |
header(4) |
對應(yīng)request.getHeader() |
headerValues |
對應(yīng)request.getHeaderValues() |
cookie(5) |
對應(yīng)request.getCookies() |
initParam(6) |
對應(yīng)ServletContext.getInitParamter() |
(1)
|
例子中的${pageContext.request.contextPath}返回的是request.getContextPath()的值,在此例中就是/13-04,,我們經(jīng)常使用這個來拼接jsp中的絕對路徑,。
這里的${pageContext.request.contextPath}是一種特殊用法,不能使用${request.contextPath}的形式替代,。
|
(2)
|
pageScope, requestScope, sessionScope, appliationScope都可以看作是Map型變量,,調(diào)用其中的數(shù)據(jù)可以使用${pageScope.name}或${pageScope["name"]}的形式,這兩種寫法是等價的,。
在某些情況下只能使用${pageScope["content-type"]},,這里不能寫成${pageScope.content-type},jsp無法解析連字符(-)會出現(xiàn)錯誤,。
|
(3)
|
需要注意的是${paramValues.name}得到的是一個字符串?dāng)?shù)組,,如果需要獲得其中某個值,還需要使用${paramValues.name[0]}指定數(shù)組中的索引,。
這與下面的${headerValues.name}是相似的,。
|
(4)
|
${header.name}會取得http請求中的header參數(shù),現(xiàn)實工作中很少用到這里的數(shù)據(jù),。
例子中使用Host是指請求訪問的主機(jī)地址,,包括ip和端口號。而Referer比較有趣,,如果用戶通過超鏈接跳轉(zhuǎn)過來的,,Referer會保存上次訪問頁面的地址,我們就可以通過它來統(tǒng)計哪些用戶是從哪里轉(zhuǎn)來的了,。
|
(5)
|
${cookie.name}將獲得對應(yīng)cookie的對象,,比如我們用jsp將一段cookie發(fā)送給客戶端。
Cookie cookie = new Cookie("username", "Username in cookie");
response.addCookie(cookie);
創(chuàng)建一個名稱為username,,值為"Username in cookie"的Cookie對象,,然后發(fā)送給客戶端。
然后我們就可以使用${cookie.username}獲得這個cookie了,,${cookie.username.name}獲得cookie名稱,,${cookie.username.value}獲得cookie值,。
|
(6)
|
ServletContext.getInitParamter()指的應(yīng)用的初始變量,這些變量都是定義在web.xml中的,。
<context-param>
<param-name>username</param-name>
<param-value>username with context param</param-value>
</context-param>
${initParam.username}就會得到這里的變量值,。
|
以上都是死記硬背的東西,建議實際用到的時候翻看一下就好了,,演示代碼都放在13-04下,,為了獲得param和cookie還要點(diǎn)擊一下最下邊的連接才可以。
el表達(dá)式中支持java中所有的操作符,,并且還有一些擴(kuò)展,,下面我們簡要做一下對照。
表 13.2. 加減乘除四則運(yùn)算
符號 |
說明 |
+ |
加 |
- |
減 |
* |
乘 |
/或div |
除 |
%或mod |
求余 |
表 13.3. 比較運(yùn)算
符號 |
說明 |
==或eq |
相等(equals) |
!=或ne |
不相等(not equals) |
<或lt |
小于(less than) |
>或gt |
大于(greater than) |
<=或le |
小于等于(less than or equals) |
>=或ge |
大于等于(greater than or equals) |
表 13.4. 邏輯運(yùn)算
符號 |
說明 |
&&或and |
邏輯和 |
||或or |
邏輯或 |
!或not |
取反 |
表 13.5. 特殊運(yùn)算
符號 |
說明 |
empty |
是否為null或空字符串 |
: |
三元運(yùn)算符 |
下面上所有運(yùn)算符的顯示結(jié)果,,順便說一下如果想在jsp中顯示${name}而不讓jsp把它當(dāng)作el計算出來,,可以寫成\${name},這樣最后顯示的結(jié)果就是${name}了,。
|