這里詳細講解如何在jsp中使用el表達式。
如果你不滿足以下任一條件,請繼續(xù)閱讀,否則請?zhí)^此后的部分,進入下一章:第 14 章 生命周期。
了解如何在jsp中使用及禁用el表達式。
了解el表達式的取值方式。
我們已經(jīng)知道el是jsp-2.0規(guī)范的一部分,tomcat-5.x版本以上都已經(jīng)能夠支持jsp-2.0規(guī)范,但在更低版本的tomcat和webphere,weblogic中還是無法使用這一便捷方式。
其實我們也可以選擇在jsp中禁止使用el表達式,使用jsp指令(directive)可以對禁用某一個jsp中的el表達式。
禁用之后的el表達式會以原樣顯示出來,如下圖所示。
為了對照,我們還在13-01下放了一個可以正常使用el表達式的例子,運行效果如下圖顯示。
在13-01/index.jsp中禁用el表達式,是使用了isELIgnore="true"這樣一條jsp指令(directive),請注意大小寫。
<%@ page isELIgnored="true" %><%pageContext.setAttribute("hello", "Hello World");%>${hello}
還有一種批量禁用el的方法,我們可以在WEB-INF/web.xml中使用jsp-property-group標簽批量禁用el,我們在13-02/WEB-INF/web.xml中進行如下配置。
<xml version="1.0" encoding="UTF-8"?><web-app 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-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表達式,使用這種方式需要注意兩點。
jsp-property-group標簽是jsp-2.0中新增功能,如果你使用低版本的web.xml(2.3或以下)就不能使用這個標簽了。
設置jsp-config會影響jsp生成servlet的過程,如果程序修改時已經(jīng)有jsp轉換成servlet并緩存在work目錄下,那么修改后需要先清除緩存,才能看到效果。
實際上還有第三種方法可以禁用掉所有jsp中的el表達式,那就是把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.sun.com/dtd/web-app_2_3.dtd"><web-app></web-app>
這個就是13-03/WEB-INF/web.xml的定義,定義了web-app的版本號是2.3,這樣一來所有的jsp都無法使用el表達式了,因為el表達式是2.4版才開始支持的功能。
說了以上三種禁用el表達式的方法,不是希望大家拋棄el表達式,相反是希望大家在自己編寫el時出現(xiàn)問題時,先去考慮是否有人在這三個地方做了設置造成el表達式的失效。建議大家多多使用el表達式,少用一些jsp中的scriptlet代碼。
使用el的時候,默認會以一定順序搜索四個作用域,將最先找到的變量值顯示出來。
如果我們有${username}這樣一個正則表達式,它回去依次調用pageContext.getAttribute("username") -> request.getAttribute("username") -> session.getAttribute("username") -> application.getAttribute("username"),只要找到某一個不為空的值就立刻返回。
這樣的確方便我們的操作,但是隨之也出現(xiàn)了另外一個問題,如果pageContext和request中有同名變量,但是我想取得request中的變量該如何是好呢?這就需要為el表達式引入作用域的概念了。
${pageScope.username}${requestScope.username}
我們可以直接訪問13-04這個應用,看看el表達式支持的所有對象。
下面我們分別對每個作用域對象進行講解。
表 13.1. el中的作用域
例子中的${pageContext.request.contextPath}返回的是request.getContextPath()的值,在此例中就是/13-04,我們經(jīng)常使用這個來拼接jsp中的絕對路徑。 這里的${pageContext.request.contextPath}是一種特殊用法,不能使用${request.contextPath}的形式替代。 | |
pageScope, requestScope, sessionScope, appliationScope都可以看作是Map型變量,調用其中的數(shù)據(jù)可以使用${pageScope.name}或${pageScope["name"]}的形式,這兩種寫法是等價的。 在某些情況下只能使用${pageScope["content-type"]},這里不能寫成${pageScope.content-type},jsp無法解析連字符(-)會出現(xiàn)錯誤。 | |
需要注意的是${paramValues.name}得到的是一個字符串數(shù)組,如果需要獲得其中某個值,還需要使用${paramValues.name[0]}指定數(shù)組中的索引。 這與下面的${headerValues.name}是相似的。 | |
${header.name}會取得http請求中的header參數(shù),現(xiàn)實工作中很少用到這里的數(shù)據(jù)。 例子中使用Host是指請求訪問的主機地址,包括ip和端口號。而Referer比較有趣,如果用戶通過超鏈接跳轉過來的,Referer會保存上次訪問頁面的地址,我們就可以通過它來統(tǒng)計哪些用戶是從哪里轉來的了。 | |
${cookie.name}將獲得對應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值。 | |
ServletContext.getInitParamter()指的應用的初始變量,這些變量都是定義在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還要點擊一下最下邊的連接才可以。