EL 表达式

常用提取:EL中的隐含对象

一、EL表达式简介

  起初 EL 表达式只是为了方便存取数据所定义的一种语言。它只能使用在 JSTL 标签中,而不能在JSP 页面中运用。一直到了 JSP2.0 版本发布后, EL 才被正式纳入为 JSP 标准规范之一。这时,它才可以直接在 JSP 页面程序中使用,只要安装的 Web 服务器能够支持 Servlet2.4/JSP2.0。

1.1 EL表达式简单使用介绍

  在 JSP2.0 之前,Web开发者只能使用表达式<%=Name%>访问系统的值,例如:

<someTags:aTag attribute="<%=pageContext.getAttribute("aName")%>">

或者调用JavaBean中的属性值:

<%= aCustomer.getAddress().getCountry() %>

  而EL表达式语言允许网页开发者使用简单的语法访问对象。比如要访问一个简单变量,可以像下面这样写:

<someTags:aTag attribute="${aName}">

  其中${aName}即为访问aName变量的EL表达式。而访问JavaBeans属性(例如获取aCustomer对象中定义的address对象变量的 country属性),可以使用:

${aCustomer.address.country}

  EL表达式还可以很好在JavaScript中得到使用,因为表达式语言正是借用了访问结构化数据的JavaScript语法。EL可以很好的和JSTL或者自定义标签结合使用,因为EL创建的初衷就是在JSTL 中使用。例如,在<c:if>标签中的不等式EL:

<c:if test=”${bean1.num < 3}”>
body content
</c:if>

  在EL中除了可以是变量、数值、对象的属性调用或者嵌套调用以及不等式判断(判断结果是Boolean类型),还可以直接包含一个字符串:

<c:out value=”an expression is ${‘${‘}expr}” />

  这样输出的字符串值为:an expression is ${expr}。
  page 指令中,有一个 isELignored 属性,它就是指定该 JSP 页面是否支持 EL表达式。如果isELignored属性值为true,即忽略EL表达,在JSP页面可以直接使用${之类的字符,Web容器式不会试图解析这些表达式。如果设置为false,当Web容器遇到“${”字符时会解析其中的表达式内容,并把结果输出。
注意:当 isELignored属性设置为false,即页面能够识别EL表达式语言,但是Web开发者又想使用“${”字符,则需要在前面加上“/”作标识。

 

1.2 EL表达式的特点和使用范围

总结起来, EL 表达式语言的使用范围以及特点包括如下:

  • 不仅仅可以在 JSTL 或者自定义标签中使用 EL, JSP2.0 开始允许 EL 在 JSP 语句以及 JavaScript语句等更广范围内使用 EL 表达式语言。
  • 在 EL 表达式语言中可以获得命名空间( PageContext 对象,它是页面中所有其他内置对象的最大集成者,通过它可以访问到其他内置对象,本书的第五章有介绍)。
  •  既可以访问一般变量,还可以访问 JavaBean 类中的属性以及嵌套属性和集合对象。
  • 在 EL 表达式中可以执行关系运算、逻辑运算以及算术运算。
  • 扩展函数可以和 Java 类的静态方法映射
  • 在 EL 表达式中可以访问 JSP 的一系列隐含对象( request、 session、 application 以及 page 等)。

二、EL语法

  EL 表达式的使用是非常简单的,所有的 EL 表达式的格式都是以“ ${”开始,并以“ }”结尾。最直接和简单的方法,就是在 EL 中使用变量名获取到值,例如:

${ username }

  当 EL 表达式中的变量不给定范围时,则表示容器会默认从 page 范围中找,再依次到 request.、session以及 application 范围(由小到大)。如果中途中找到 username 变量,则直接返回,否则返回 NULL。下面列出了 EL使用到的变量属性范围的名称:

  • 属性范围 page:在 EL 中使用名称 pageScope,例如${pageScope.username},则表示在 page 范围中找 username 变量,找不到直接返回 NULL。
  • 属性范围 request:在 EL 中使用名称 requestScope。
  • 属性范围 session:在 EL 中使用名称 sessionScope。
  • 属性范围 application:在 EL 中使用名称 applicationScope。

2.1 在EL中可以包含的文字

JSP 表达式语言( EL)定义了可以在表达式中使用的文字包括以下:

  • Boolean: ture 和 false。
  • Integer:与 Java 类似,可以包含任何正数或者负数,例如 24、 56、 -54 等。
  • Floating Point:与 Java 类似,可以包含任何正的或者负的浮点数,例如-1.8E-5、 4.567。
  • String:任何由引号或者双引号限定的字符串。对于单引号、双引号和反斜杠,使用反斜杠字符作为转义序列。必须注意,如果在字符串两端使用双引号,则但引号不需要转义。
  • NULL:返回 null。

下面逐一举例:
${false}包含 Boolean 类型、 ${3*8}包含整数类型 Integer、 ${5.678}包含浮点型、 ${“string”}或者${‘string’}包含字符串、 ${NULL}表示返回为空值。

2.2 操作符“ []”和“ .”

  在 EL 中,可以使用操作符“ []”和“ .”来取得对象的属性。例如:${user.name}或者${user[name]}表示取出对象 user 中的 name 属性值。
  另外在 EL 中可以使用[]操作符来读取 Map、 List 或者对象集合中的数据,例如在 Session 域中存在一个数组 schools:获取数组中第二位数值:

${sessionScope.schools[1]}

  如果 schools 是 School 对象集合类,则可是获取第二位对象中的 name 属性值:

${sessionScope.shools[1].name}

  这里的 sessionScope 是在 EL 表达式中的调用 Session 内置对象的名称。
  如果需要 EL 表达式来访问一个 JavaBean 中的属性值, JavaBean 的定义如下:

<jsp:useBean id=”user” class=”cn.User” />

  对 JavaBean 类中属性的引用: ${user.name}或者${user[“name”]}。
注意:当属性名中包含了一些特殊符号时,例如“.”或者“-”等非字母或者数字符号时,就只能使用[]格式来访问属性值了,例如:${sessionScope.user[user_name]}是正确的,而${sessionScope.user.user_name}是不正确的。
  另外一种情况也必须使用[]符号来引用属性值,当某个对象的属性名使用某一个变量(假设这里变量为 AttributeName)来给定的,例如:
${sessionScope.user[AttributeName]},这里的变量 AttributeName 可以在之前进行赋值。例如 AttributeName 变量赋值为 name,则以上 EL 表达式等价于:${sessionScope.user.name}

2.3 EL中的基本算术操作符

  在 JSP 中的表达式语言( EL)提供了如下多个运算操作符,其中大部分是 Java 中常用的操作符。

算术操作符 说明 范例 结果
“加法”操作${23+5}28
“减法”操作${34-6}28
*“乘法”操作${3*8}24
/或者div“除法”操作${8/2}或者${8 div 2}4
%或者mod“求余”操作${17/4}或者${17 mod 4}1

“+”、“-”和“ *”操作符: A+B、 A-B 和 A*B

  • 如果 A 和 B 同为 NULL 时,直接返回 0。
  • 如果 A 和 B 其中有一个为 Float、 Double 或者包含了“ .”、“ e”或者“ E”字符的字符串,则强行把 A 和 B 转换成 Double 类型,其中有三种情况:
    • 运算符为“+”时,返回 A.add(B)
    • 运算符为“-”,则返回 A.subtract(B)
    • 运算符为“ *”,则返回 A.multiply(B)
  • 否则,强行把 A 和 B 转为 Long 类型,然后再运行相应的运算
  • 如果运算操作出现异常,则报错

“ /”或者 div 操作符: A/B 或者 A div B

  • 如果 A 和 B 同时为 NULL,则返回 0
  • 否则,强行把 A 和 B 转换成 Double 类型,再执行相应的操作运算
  • 如果运算操作出现异常,则报错

“ %”或者“ mod”操作符: A%B 或者 A mod B

  • 如果 A 和 B 同时为 NULL,则返回 0
  • 如果 A 或者 B 其中一个为 Float、 Double 或者包含了“ .”、“ e”或者“ E”字符的字符串,则强行把 A 和 B 转换成 Double 类型,再执行相应的操作运算
  • 否则,强行把 A 和 B 转换成 Long 类型,再执行相应操作运算
  • 如果运算操作出现异常,则报错

一元负号操作符: -A

  • 如果 A 为 NULL,则返回 0
  • 如果 A 为一个字符串,又分如下几种情况:
    • 如果这个字符串包含“ .”、“ e”或者“ E”字符,则把 A 强行转换成 Double 类型,再执行相应操作运算
    • 否则,强行把 A 转换成 Long 类型,再执行相应操作运算
    • 如果运算操作出现异常,则报错
  • 如果 A 是一个 Byte、 Short、 Integer、 Long、 Float 或者 Double 类型时,同样可能出现两种情况:
    • 直接按照原来的类型执行相应的操作运算
    • 如果出现操作异常,则报错
  •  否则,出现异常,报错

2.4 EL中的关系操作符

EL 中使用的关系操作包括如下六种,如下表:

关系操作符 说明 范例 结果
= =或者eq“等于”判断${5= =10}或者${5 eq 10}false
!=或者ne“不等于”判断${5 != 10}或者${5 ne 10}true
<或者lt“小于”判断${3 < 5}或者${3 lt 5}true
>或者gt“大于”判断${3 > 5}或者${3 gt 5}false
<=或者le“小于等于”判断${4 <= 4}或者${4 le 4}true
>=或者ge“大于等于”判断${4 >= 6}或者${4 ge 6}false

A{< or lt、 > or gt、 <= or le、 >= or ge}B 操作符

  • 如果 A 值等于 B 时,操作符为“ <=”或者“ le”、“ >=”或者“ ge”,则返回 true。否则,操作符为“ <”或者“ lt”、“ >”或者“ gt”时,返回 false
  • 如果 A 是 NULL,或者 B 是 NULL,则返回 false
  • 如果 A 或者 B 是 Float 或者 Double 类型,则强行把 A 和 B 转换成 Double 类型,然后再执行相应的操作运算符
  • 如果 A 或者 B 是 Byte、 Short、 Character、 Integer 或者 Long 类型时,则强行把 A 和 B 转换成Long,然后执行相应的操作运算符
  • 如果 A 或者 B 是一个字符串,则强行把 A 和 B 全都转换成字符串,再进行相应的比较操作
  • 如果拿 A 是去比较,存在两种情况:
    1. 若 A.compareTo(B)产生异常,则报错
    2. 否则,返回 A.compareTo(B)的比较结果
  • 如果拿 B 是去比较,也存在两种情况:
    1. 若 B.compareTo(A)产生异常,则报错
    2. 否则,返回 B.compareTo(A)的比较结果
  • 否则,产生异常,报错

A{== or eq、 != or ne}B 操作符

  • 如果 A 等于 B,操作符为“==”或者“ eq”时,返回 true;否则,操作符为“!=”或者“ ne”时,返回 false
  • 如果 A 为 NULL 或者 B 为 NULL 时,则对操作符“==”或者“ eq”,返回 false;如果操作符是“!=”或者“ ne”,则返回 true
  • 如果 A 或者 B 是 Float 或者 Double 类型,则强行把 A 和 B 转换成 Double 类型,然后再执行相应的操作运算符
  • 如果 A 或者 B 是 Byte、 Short、 Character、 Integer 或者 Long 类型时,则强行把 A 和 B 转换成Long 类型,然后再执行相应的操作运算符
  •  如果 A 或者 B 是 Boolean 类型,则强行把 A 和 B 转换成 Boolean 类型之后再执行相应的操作运算府
  • 如果 A 或者 B 是字符串类型,则强行把 A 和 B 转换成字符串类型,再执行两者之间的比较
  • 如果在执行 A.equals(B)时产生异常,报错,否则返回比较结果。

2.5 逻辑操作符

逻辑操作符包括如下几种,如表所示:

逻辑操作符 说明 范例
&& 或者 and“与”操作符${num >5 && num <10}
|| 或者 or“或”操作符${num <5 || num > 11}
! 或者 not“非”操作符${!name.equals(“zzb”)}

A{&& 或者 and、 ||或者or}B逻辑操作

执行该操作符时,首先强行把 A 和 B 转换成Boolean类型,然后再执行相应的操作运算符。

  • 如果 A 和B同为true,当操作符为“&&”时,返回true;操作符为“||”时,返回true。
  • 如果 A 和B其中一个为true,另一个为false。当操作符为“&&”时,返回false;操作符为“||”时,返回true。
  • 如果 A 和B同为false。当操作符为“&&”时,返回false;操作符为“||”时,则返回false。
  • 否则,执行过程产生异常,报错。

注意:在执行过程中,只要表达式结果一旦确定,运算过程就会停止,例如,A && B && C或者A and B and C,则一旦计算到A为false,就会立即停止计算,并返回false。
  “||”操作符也同样,例如 A || B || C,则一旦检测到第一个(A、B或者C)为true,则停止计算,直接返回true。
  对“ &&”操作符来讲,只要检测到一个false,则整体为false;对“||”操作符来说,只要检测到一个true,则整体返回true。

“非”操作符: !A

执行该操作符之前,会强行把 A 转换成Boolean类型,然后再执行“非”或者“反”操作:

  • 如果 A 判断为false,执行“!”操作之后,返回结果true
  • 如果 A 判断为true,执行完“!”操作之后,返回结果false
  • 否则,执行过程发生异常,报错

2.6 Empty操作符

  这个“ empty”操作符是一个前缀形式的操作符,它使用来判断某个变量是否为 NULL 或者为空,在 EL 中的使用格式如下:${empty user.name},判断 user 对象 name 属性值是否为 NULL 或者空。“ empty”操作符的运算规则如下:

  • 如果 A 为 NULL,则返回 true。
  • 否则,如果 A 是一个空的字符串,则返回 true。
  • 否则,如果 A 是一个空的数组,则返回 true。
  • 否则,如果 A 是一个空的 Map 集合类,则返回 true。
  • 否则,如果 A 是一个空的 List 集合类,则返回 true。
  • 否则,返回 false。

2.7 其他操作符

包括的其他操作符还有:条件操作符和括号操作符。

条件操作符

  EL 中还可以使用以下形式的条件操作符:

${A ? B : C}

  其中 A 为判断表达式,当 A 为 true 时,返回 B 表达式执行的结果;如果 A 为 false,则返回 C 表达式执行之后的结果。

括号操作符

  在 EL 中也可以包含括号,例如:

${ (a * (b + c) ) }

括号主要是使用来改变执行优先权,所有操作符的优先级顺序如下(由上往下,由左往右):

  • []
  • ()
  • -(负)、 not、!、 empty
  • *、 /、 div、 %、 mod
  • +、-(减)
  • <、 >、 <=、 >=、 lt、 gt、 le、 ge
  • ==、!=、 eq、 ne
  • &&、 and
  • ${A?B:C}

三、EL中的隐含对象

  为了方便地获得 Web 应用程序中的相关数据, EL 表达式语言定义了一些隐含对象。隐含对象总共有 11 个,这样使得 EL 能够更加方便地获取到数据。
  这 11 隐含对象能够很方便地读取到 session、 cookie、 HttpHeader 以及用户提交表单( param)等,具体请查看如下表所示:

  注意:有很多读者会把 EL 中定义的隐含对象和 JSP 中定义的隐含对象相混淆,其实只有一个对象是它们两者所共有的,即 PageContext 对象。这样 EL 也可以访问到JSP 中的其他隐含对象,这是因为PageContext 对象拥有访问 JSP 中所有其他 8 个隐含对象的权限。实际上,这也是将 PageContext 对象包含在 EL 隐含对象中的主要原因。

3.1 EL中的pageContext隐含对象实例演示

<body>
	<h3>EL中的pageContext隐含对象</h3>
	<hr>
	<table border="1">
		<tr>
			<td align="center">pageContext隐含对象的方法调用</td>
			<td align="center">结果</td>
	  </tr>
	  <tr><!-- 取得请求的参数字符串 -->	  	
	  	<td>\${pageContext.request.queryString}:</td>
	    <td><c:out value="${pageContext.request.queryString}" /></td>
	  </tr>
	  <tr><!-- 取得请求的URL,但不包含请求的参数字符串 -->	
	  	<td>\${pageContext.request.requestURL}:</td>
	    <td><c:out value="${pageContext.request.requestURL}" /></td>
	  </tr>
	  <tr><!-- Web application的名称 -->	
	  	<td>\${pageContext.request.contextPath}:</td>
	  	<td><c:out value="${pageContext.request.contextPath}" /></td>
	  </tr>
	  <tr><!-- 取得HTTP的方法(GET或者POST) -->	
	  	<td>\${pageContext.request.method}:</td>
	  	<td><c:out value="${pageContext.request.method}" /></td>
	  </tr>
	  <tr><!-- 取得使用的协议(HTTP/1.1、HTP/1.0) -->	
	  	<td>\${pageContext.request.protocol}:</td>
	  	<td><c:out value="${pageContext.request.protocol}" /></td>
	  </tr>
	  <tr><!-- 取得用户名称 -->	
	  	<td>\${pageContext.request.remoteUser}:</td>
	  	<td><c:out value="${pageContext.request.remoteUser}" /></td>
	  </tr>	 	  	
	  <tr><!-- 取得用户的IP地址 -->	
	  	<td>\${pageContext.request.remoteAddr}:</td>
	  	<td><c:out value="${pageContext.request.remoteAddr}" /></td>
	  </tr>
	  <tr><!-- 判断session是否为新的。所谓新的session,就是刚由server产生而client尚未使用的 -->	
	  	<td>\${pageContext.session.new}:</td>
	  	<!-- 注意:此处与其它不一样,其它都是session.something,这里如果也这样写就会解析错误 -->
	  	<td><c:out value="${pageContext.session['new']}" /></td>
	  </tr>
	  <tr><!-- 取得session的ID -->	
	  	<td>\${pageContext.session.id}:</td>
	  	<td><c:out value="${pageContext.session.id}" /></td>
	  </tr>	   
	  <tr><!-- 取得主机信息 -->	
	  	<td>\${pageContext.servletContext.serverInfo}:</td>
	  	<td><c:out value="${pageContext.servletContext.serverInfo}" /></td>
	  </tr>	 
	</table>
</body>

注:需要引入JSTL核心依赖

3.2 EL中header、 headerValues、 param、 paramValues隐含对象实例演示

  这四个映射用来获取请求参数和请求头的值。因为 HTTP 协议允许请求参数和请求头具有多个值,所以它们各有一对映射。每对中的第一个映射返回请求参数或头的主要值,通常是恰巧在实际请求中首先指定的那个值。每对中第二个映射允许检索参数或头的所有值。这些映射中的键是参数或头的名称,但这些值是 String 对象的数组,其中的每个元素都是单一参数值或头值。
  param 和 paramValues 两隐含对象是取得用户的请求参数,类似于 JSP 中的下列方法:

  • request.getParameter(String name)
  • request.getParameterValues(String name)

下面创建 paramsubmit.jsp 和 param.jsp 页面来演示这四个隐含变量的使用方法, paramsubmit.jsp 用于提交参数,param.jsp接收数据,示例如下:

paramsubmit.jsp

<body>
	<h3>EL中的隐含对象:header,headerValues,param,paramValues</h3>
	<hr>
	<form action="param.jsp" method="post">
		<table width="400" align="center" border="1">
			<tr>
				<td width="60">姓名:</td>
				<td> <input type="text" name="name" width="15" /></td>
			</tr>
			<tr>
				<td>性别:</td>
				<td> <input type="radio" name="sex" value="male" checked />男
					<input type="radio" name="sex" value="female" />女
				</td>
			</tr>
			<tr>
				<td>专业:</td>
				<td> <select name="specialty">
						<option value="计算机科学" selected>计算机科学</option>
						<option value="通信">通信</option>
						<option value="管理科学与工程">管理科学与工程</option>
				</select></td>
			</tr>
			<tr>
				<td>爱好:</td>
				<td> <input type="checkbox" name="habit" value="电影" />电影
					<input type="checkbox" name="habit" value="读书" />读书 <input
					type="checkbox" name="habit" value="羽毛球" />羽毛球 <input
					type="checkbox" name="habit" value="篮球" />篮球 <input
					type="checkbox" name="habit" value="旅游" />旅游
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center"><input type="submit" value="提交" />
					| <input type="reset" value="重置" /></td>
			</tr>
		</table>
	</form>
</body>

param.jsp

<body>
	<h3>EL中的隐含对象:header,headerValues,param,paramValues</h3>
	<hr>
	<fmt:requestEncoding value="GBK" />
	HTTP连接头部的host值: ${header["host"]}
	<br> HTTP头部的accept值: ${header.accept}
	<br> HTTP头部的user-agent值: ${header["user-agent"]}
	<br>
	<hr width="50%" align="left">
	姓名:
	<c:out value="${param.name}" />
	<br> 性别:
	<c:out value="${param.sex}" />
	<br> 专业:
	<c:out value="${param['specialty']}" />
	<br> 兴趣:
	<c:out value="${paramValues.habit[0]}" />
	<c:out value="${paramValues.habit[1]}" />
	<c:out value="${paramValues.habit[2]}" />
	<c:out value="${paramValues.habit[3]}" />
	<c:out value="${paramValues.habit[4]}" />
</body>

注:需要引入JSTL核心标签库和国际化标签库。

3.3 EL中pageScope、 requestScope、 sessionScope、 applicationScope隐含对象实例演示

  这四个隐含对象表示先前讨论的各种属性作用域。可以用它们来查找特定作用域中的标识符,而不用依赖于 EL 在默认情况下使用的顺序(首先 page,然后 request、 session,再 application)查找过程。
  它们和 JSP 中的 page、 request、 session 以及 application 隐含对象非常相似,但是有一点要注意的,这里的四个隐含对象只能用来取得范围属性值,而不能取得其他相关信息。
  下面创建一个 scope.jsp 文件。首先使用<c:set>标签在不同的范围内( page、 request、 session 和application)设置相同的 name 变量,然后调用相应的 pageScope、 requestScope、 sessionScope 以及applicationScope 隐含对象来取得 name 变量值。

<head><title>pageScope、requestScope、sessionScope以及applicationScope隐含对象在EL中使用</title></head>
<body>
	<h4>EL中的pageScope、requestScope、sessionScope以及applicationScope隐含对象</h4>
	<hr>
<c:set var="name" value="pageValue" scope="page" />
<c:set var="name" value="requestValue" scope="request" />
<c:set var="name" value="sessionValue" scope="session" />
<c:set var="name" value="applicationValue" scope="application" />

\${name}: <c:out value="${name}" /> <br>
\${pageScope.name}: <c:out value="${pageScope.name}" /> <br>
\${requestScope.name}: <c:out value="${requestScope.name}" /> <br>
\${sessionScope.name}: <c:out value="${sessionScope.name}" /> <br>
\${applicationScope.name}: <c:out value="${applicationScope.name}" /> <br>
</body>

3.4 cookie和initParam隐含对象

  cookie 隐式对象提供了对由请求设置的 cookie 名称的访问。这个对象将所有与请求相关联的 cookie名称映射到表示那些 cookie 特性的 Cookie 对象。
  JSTL 标准标签并没有提供设置 cookie 的动作,因此这个动作通常都是开发者必须要去做的事情,而不是交给前端。如已经在 cookie 中设置了一个 name 的值,则可以通过${cookie.name}来取得它的值。
  最后一个 EL 隐式对象 initParam 也是一个映射,它储存与 Web 应用程序相关联的所有上下文的初始化参数的名称和值。初始化参数是通过 web.xml 部署描述符文件指定的,该文件位于应用程序的WEB-INF 目录中。例如在 web.xml 文件中设定如下:

<context-param>
<param-name>username</param-name>
<param-value>Johnson</param-value>
</content-param>

  那么在程序当中就可以直接使用${initParam.username}来取得 username 参数的值“ Johnson”。
参考资料:

  • 《JSP宝典》

赞赏

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值