6
第六章
Expression Language
本章将分以下 8 节,详细介绍 Expression Language 的语法和使用:
6-1 EL 简介
6-2 EL 语法
6-3 EL 隐含对象
6-4 EL 算术运算符
6-5 EL 关系运算符
6-6 EL 逻辑运算符
6-7 EL 其他运算符
6-8 EL
Functions
JSP2.0
技术手册
第六章
Expression Language
100
6-1 EL
简介
EL 全名为 Expression Language,它原本是 JSTL 1.0 为方便存取数据所自定义的语言。当时
EL 只能在 JSTL 标签中使用,如下:
<c:out value="${ 3 + 7}">
程序执行结果为 10。但是你却不能直接在 JSP 网页中使用:
<p>Hi ! ${ username }</p>
到了 JSP 2.0 之后,EL 已经正式纳入成为标准规范之一。因此,只要是支持 Servlet 2.4 / JSP
2.0 的 Container,就都可以在 JSP 网页中直接使用 EL 了。
除了 JSP 2.0 建议使用 EL 之外,JavaServer Faces( JSR-127 ) 也考虑将 EL 纳入规范,由此
可知,EL 如今已经是一项成熟、标准的技术。
注意
假若您所用的 Container 只支持 Servlet 2.3/JSP 1.2,如:Tomcat 4.1.29,您就不能在 JSP 网页中
直接使用 EL,必须安装支持 Servlet 2.4 / JSP 2.0 的 Container。
6-2 EL
语法
EL 语法很简单,它最大的特点就是使用上很方便。接下来介绍 EL 主要的语法结构:
${sessionScope.user.sex}
所有 EL 都是以 ${ 为起始、以} 为结尾的。上述 EL 范例的意思是:从 Session 的范围中,
取得用户的性别。假若依照之前 JSP Scriptlet 的写法如下:
User user = (User)session.getAttribute("user");
String sex = user.getSex( );
两者相比较之下,可以发现 EL 的语法比传统 JSP Scriptlet 更为方便、简洁。
6-2-1 .
与
[ ]
运算符
EL 提供 . 和 [ ] 两种运算符来存取数据。下列两者所代表的意思是一样的:
${sessionScope.user.sex}
等于
${sessionScope.user["sex"]}
. 和 [ ] 也可以同时混合使用,如下:
JSP2.0
技术手册
6-2 EL
语法
101
${sessionScope.shoppingCart[0].price}
回
传结果为 shoppingCart 中第一项物品的价格。
不过,以下两种情况,两者会有差异:
(1) 当要存取的属性名称中包含一些特殊字符,如 . 或 – 等并非字母或数字的符号,就一
要使用 [ ],例如: 定
${user.My-Name }
上
述是不正确的方式,应当改为:
${user["My-Name"] }
(2) 我们来考虑下列情况:
${sessionScope.user[data]}
此时,data 是一个变量,假若 data 的值为"sex" 时,那上述的例子等于
${sessionScope.user.sex};假若 data 的值为"name"时,它就等于${sessionScope.user.name}。
此,如果要动态取值时,就可以用上述的方法来做,但 . 无法做到动态取值。 因
接下来,我们更详细地来讨论一些情况,首先假设有一个 EL:
${expr-a[expr-b]}
(1) 当 expr-a 的值为 null 时,它会回传 null。
(2) 当 expr-b 的值为 null 时,它会回传 null。
(3) 当 expr-a 的值为一 Map 类型时:
● 假若 !value-a.containsKey(value-b)为真,则回传 null。
● 否则回传 value-a.get(value-b)。
(4) 当 expr-a 的值为 List 或 array 类型时:
● 将 value-b 的值强制转型为 int,假若不能转型为 int 时,会产生 error。
●然后,假若 value-a.get(value-b) 或 Array.get(value-a, value-b) 产生
ArrayIndexOutOfBoundsException 或 IndexOutOfBoundsException 时,则回传 null。
● 假若 value-a.get(value-b)或 Array.get(value-a, value-b)产生其他的异常时,则会产生 error。
● 最后都没有任何异常产生时,回传 value-a.get(value-b)或 Array.get(value-a, value-b)。
(5) 当 expr-a 的值为
JavaBean 对象时:
● 将 value-b 的值强制转型为 String。
● 假若 getter 产生异常时,则会产生 error。若没有异常产生时,则回传 getter 的结果。
6-2-2 EL
变量
EL 存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为
username 的变量。因为我们并没有指定哪一个范围的 username,所以它的默认值会先从 Page
范围找,假如找不到,再依序到 Request、Session、Application 范围。假如途中找到 username,
JSP2.0
技术手册
第六章
Expression Language
102
就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传 null(见表 6-1):
表 6-1
属性范围 在 EL 中的名称
Page
PageScope
Request
RequestScope
Session
SessionScope
Application
ApplicationScope
自动搜索顺序
我们也可以指定要取出哪一个范围的变量(见表 6-2):
表 6-2
范 例 说 明
${pageScope.username}
取出 Page 范围的 username 变量
${requestScope.username}
取出 Request 范围的 username 变量
${sessionScope.username}
取出 Session 范围的 username 变量
${applicationScope.username}
取出 Application 范围的 username 变量
其中,pageScope、requestScope、sessionScope 和 applicationScope 都是 EL 的隐含对
象,由它们的名称可以很容易猜出它们所代表的意思,例如:${sessionScope.username}是取
出 Session 范围的 username 变量。这种写法是不是比之前 JSP 的写法:
String username = (String) session.getAttribute("username");
容易、简洁许多。有关 EL 隐含对象在 6-3 节中有更详细的介绍。
6-2-3
自动转变类型
EL 除了提供方便存取变量的语法之外,它另外一个方便的功能就是:自动转变类型,我们
来看下面这个范例:
${param.count + 20}
假若窗体传来 count 的值为 10 时,那么上面的结果为 30。之前没接触过 JSP 的读者可能
会认为上面的例子是理所当然的,但是在 JSP 1.2 之中不能这样做,原因是从窗体所传来的值,
它们的类型一律是 String,所以当你接收之后,必须再将它转为其他类型,如:int、float 等
等,然后才能执行一些数学运算,下面是之前的做法:
String str_count = request.getParameter("count");
int count = Integer.parseInt(str_count);
count = count + 20;
JSP2.0
技术手册
6-2 EL
语法
103
接下来再详细说明 EL 类型转换的规则:
(1) 将 A 转为 String 类型
● 假若 A 为 String 时:回传 A
● 否则,当 A 为 null 时:回传 ""
● 否则,当 A.toString( )产生异常时:错误!
● 否则,回传 A.toString( )
(2) 将 A 转为 Number 类型的 N
● 假若 A 为 null 或 "" 时:回传 0
● 假若 A 为 Character 时:将 A 转为 new Short((short)a.charValue( ))
● 假若 A 为 Boolean 时:错误!
● 假若 A 为 Number 类型和 N 一样时:回传 A
● 假若 A 为 Number 时:
·假若 N 是 BigInteger 时:
·假若 A 为 BigDecimal 时:回传 A.toBigInteger( )
·否则,回传 BigInteger.valueOf(A.longValue( ))
·假若 N 是 BigDecimal 时:
·假若 A 为 BigInteger 时:回传 A.toBigDecimal( )
·否则,回传 BigDecimal.valueOf(A.doubleValue( ))
·假若 N 为 Byte 时:回传 new Byte(A.byteValue( ))
·假若 N 为 Short 时:回传 new Short(A.shortValue( ))
·假若 N 为 Integer 时:回传 new Integer(A.intValue( ))
·假若 N 为 Long 时:回传 new Long(A.longValue( ))
·假若 N 为 Float 时:回传 new Float(A.floatValue( ))
·假若 N 为 Double 时:回传 new Double(A.doubleValue( ))
·否则,错误!
● 假若 A 为 String 时:
·假若 N 是 BigDecimal 时:
·假若 new BigDecimal(A)产生异常时:错误!
·否则,回传 new BigDecimal(A)
·假若 N 是 BigInteger
时:
·假若 new BigInteger(A)产生异常时:错误!
·否则,回传 new BigInteger(A)
·假若 N.valueOf(A)产生异常时:错误!
·否则,回传 N.valueOf(A)
● 否则,错误!
(3) 将 A 转为 Character 类型
● 假若 A 为 null 或 "" 时:回传 (char)0
JSP2.0
技术手册