2.5 表达式语言——EL
大量Java脚本使得JSP页面难以维护,于是,一种类似JavaScript的语言——EL表达式可用于在网页上生成动态内容,并代替JSP脚本元素的技术被推出。
2.5.1 基本语法
${EL expression}
其中,$是EL语法中的输出符号,表示EL中表达式的开始;{是起始分隔符;EL expression为指定表达式;}是结束分隔符。EL有效表达式可以包含文字、操作符、变量(对象引用)和函数调用等。
1、EL关键字
EL保留的关键字有16个,它们是不能表示其他含义的。这16个分别是:
and gt true null or lt false empty
eq ge instanceof div ne not le mod
2、访问运算符“.”和“【】”
下面两条语句所代表的意思是一样的:
${sessionScope.user.age};
${sessionScope.user[afe]}.
两种访问运算符也可以混合使用,例如:
${sessionScope.shoppingCart[0].value}
不过在以下两种情况下,两者会有差异:
1)当要存取的属性名称中包含一些特殊字符时,如".’或“—”等并非字母或数字的符号,就一定要使用“【】”,例如:
${user.My-Name}是错误的,应该改为${user["My-Name"]}
2)“【】”比“.”能更好地支持动态取值。例如,${sessionScope.user[data]},此时data是一个变量,假若data值为sex,则上述例子等于${sessionScope.user[sex]};假若data值为name,则上述例子等于${sessionScope.user[name]}。但“.”无法做到动态取值。
3、算术运算
EL支持通用的算术运算,包括+、-、*、/、%,其中除法运算也可以用div表示,模运算也可以用mod表示。
在表达式中也可以使用括号改变运算的优先顺序,也可以用减号表示负数。在EL的除法中,如果除以0,返回值为无穷大(infinity),而不是错误。EL的算术运算符的优先顺序如下:
1)括号:()
2)负号:—
3)乘、除、模
4)加、减
4、关系运算
EL支持的关系运算包括等于(==)、非等于(!=)、小于、大于、不小于、不大于等,也可以用eq、ne、lt、gt、le、ge分别表示上面的关系运算符。
EL关系表达式的返回值为Boolean值且运算的优先次序低于算术运算,其中关系运算符之间的优先顺序为:
1)< > <= >=
2)== !=
5、逻辑运算
包括与(&&)、或(||)、非(!),也可以用and、or、not代替。
逻辑运算运算优先级低于关系运算,逻辑运算之间的优先顺序为:
1)!
2)&&
3)||
6、empty运算符
如果操作数数值为null则返回true,或者操作数本身是一个空容器、空数组或长度为0的字符串等也返回true。空容器是指不包含任何元素的容器。
7、自动类型转换
如果一个JSP页面需要处理request对象中的属性attr,以前的处理用代码表示为:
String strAttr=(String)request.getAttribute("attr");
int attrInt=Integer.parseInt(strAttr);
attrInt=attrInt+1;
其中,由于getAttribute()方法返回值的类型是Object,如果要作为整型使用,需要在代码中进行转换。如果用EL表达式,可以直接用${param.attr+1}来完成类型转换。
EL表达式中自动类型转换的规则如下:
(1)Object转换为数值
如果object为Boolean类型,出错;
如果object==null,返回0;
如果object==“”,返回0;
如果object为字符串,且字符串可以转换成数值,则返回数值,否则出错。
(2)object转换成String
object为数值型数据时,依据其值直接转换成字符串,如100.23转换成“100.23”
如果object==null,返回长度为0的字符串:“”;
如果object.toString()产生异常,会出错,否则返回object.toString()。
注意:JSP会把${xxx}的内容都认为是EL表达式,里面的内容都会被计算,如果只是想输出${xxx}的字符串,需要转义。一种方式是在${xxx}前加上\,另一种写法是${'${'{xxx},表示xxx会包含在${}中作为一个字符串表示。
举例:el1.jsp
<%@ 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>
<h1>EL表达式</h1>
<table border="1">
<tr>
<th>运算</th>
<th>EL表达式</th>
<th>结果</th>
</tr>
<tr>
<td>与</td>
<td>\${true and true}</td>
<td>${true and true}</td>
</tr>
</table>
</body>
</html>
截图:
2.5.2 隐式对象
EL还可以对JSP页面的相关信息进行操作,为了方便这种操作,EL提供了11个隐式对象,如下图:
1、pageContext对象
2、param和paramValues对象
使用param可以访问请求的参数值,而如果一个参数名对应多个值时,就需要用到后一个对象。${param.attr}会输出请求参数的值,如果这个值不存在,输出空字符串“”而不是null。
举例:sub.jsp
<%@ 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>
<form method="post" action="Param.jsp">
<p>姓名:<input type="text" name="username" size="15"/></p>
<p>密码:<input type="password" name="password" size="15"/></p>
<p>性别:<input type="radio" name="sex" value="Male" />男
<input type="radio" name="sex" value="Female" checked/>女</p>
<p>年龄:<input type="text" name="age" size="15"/></p>
<p>兴趣:<input type="checkbox" name="habit" value="学习">学习
<input type="checkbox" name="habit" value="旅游">旅游
<input type="checkbox" name="habit" value="音乐">音乐
</p>
<p><input type="submit" value="发送">
<input type="reset" value="重置"></p>
</form>
</body>
</html>
Param.jsp
<%@ 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.setCharacterEncoding("utf-8"); %>
姓名:${param.username }<br/>
密码:${param.password }<br/>
性别:${param.sex }<br/>
年龄:${param.age }<br/>
兴趣:${paramValues.habit[0] } ${paramValues.habit[1] }
</body>
</html>
截图:
3、header和headerValues对象
header储存用户浏览器和服务端用来沟通的数据,使用header对象可以访问HTTP请求的一个具体的header值;headerValues对象可以访问所有HTTP请求的header值。
4、cookie对象
JSTL中并没有提供设定cookie的对象,例如要取得cookie中一个设定名称为ao的值,可以使用${cookie.ao}来取得。
5、initParam对象
在EL中使用这个对象,可以访问Servlet上下文的初始参数。例如,一般的方法String userid=(String)application.getInitParameter("userid"),其实就可以使用${initParam.userid}来取得名称为userid的值。
6、属性范围
涉及有效范围的四个对象为:pageScope、requestScope、sessionScope、applicationScope。
${attr}会依次在上面提到的四个范围内查找属性名称为attr的属性对象,并输出第一次碰到的值。
而${sessionScope.attr}只在会话范围内查找。