EL称为表达式语言,即Expression Language,是用来替代表达式<%=%>的技术,从而简化JSP文件。EL的语法是以“${”开始,以“}”结束。
EL中共有11个内置对象,可以方便地输出相应信息。根据内置对象的作用和特征,可以分为四大类
param:param用来输出请求参数的值,格式为${param.请求参数名字}
使用表达式:<%=request.getParameter("name")%>
使用EL:${param.name}
paramValues:用来获取一对多的参数值,返回一个数组。
比如某请求参数是通过checkbox传递的,名字为hobbies,要输出所有hobbies值中的第一个值,可以使用如下两种方式:
使用表达式:<%=request.getParameterValues("hobbies")[0]%>
使用EL:${paramValues.hobbies[0]}
HttpSession session=request.getSession();
ServletContext application=this.getServletContext();
Customer cust2=new Customer("custname2","pwd2");
Customer cust3=new Customer("custname3","pwd3");
Customer cust4=new Customer("custname4","pwd4");
Listlist=new ArrayList();
list.add(cust2);
list.add(cust3);
list.add(cust4);
request.setAttribute("cust2",cust2);
session.setAttribute("cust3",cust3);
application.setAttribute("cust4",cust4);
request.setAttribute("list",list);
request.getRequestDispatcher("testEL.jsp").forward(request, response);
上述代码在请求、会话、上下文中都存储了一个Customer类型对象,另外还在请求中存储了一个集合类型的对象。然后将请求转发到testEL.jsp页面,该JSP中有如下代码:
${cust1.custname}
上述EL中没有指定cust1属性的范围,那么容器将从page开始,依次到request、session、application中去查找名为cust1的属性,直到找到为止。如果一直到application中依然没有找到,则认为cust1为null,不显示任何内容,也不会报错。
然而,如果有如下的表达式:
<%=cust0.getCustname()%>
容器将认为cust0是JSP的局部变量,而不会将cust0作为属性处理。
EL中提供了4个与属性有关的内置对象,用来便捷地显示不同范围的属性。这4个内置对象是pageScope、requestScope、sessionScope、applicationScope,分别用来返回页面范围、请求范围、会话范围以及上下文范围的属性值。上面的表达式可以使用下面的EL替代:
${pageScope.cust1.custname}
${requestScope.cust2.custname}
${sessionScope.cust3.custname}
${applicationScope.cust4.custname}
${requestScope.list[1].custname}
比起表达式语言,使用EL获取属性的代码简化很多。例如,EL表达式requestScope.cust2.custname首先将获取请求范围内的cust2属
性,进一步调用cust2属性的getCustname方法,输出该方法的返回值。值得注意的是,属性的类中必须有符合编码规范的getXXX方法:
get后第一个字母大写,其他字母小写,没有参数,有返回值。如果类中没有符合JavaBean规范的getXXX方法,EL表达式将出错。也就
是说,如果Customer类中没有一个声明形式为public String getCustname()的方法,那么表达式requestScope.cust2.custname将出
错。
3.其他内置对象。
① cookie:用来获取cookie的值。
${cookie.JSESSIONID.value}
上述代码将输出名字为JSESSIONID的cookie的值。
② initParam:用来输出上下文参数的值。
在web.xml中配置上下文参数:
path
/WEB-INF/props
在JSP中使用EL输出path的值:
${initParam.path}
③ header:输出某一个请求头的值。
${header.accept}
输出请求头accept的值,例如:
image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
④ headerValues:如果某个请求头的值有多个,则使用headerValues返回一个数组
${headerValues.cookie[0]}
上述代码将返回请求头cookie中的第一个值,例如:
JSESSIONID=A6A22CA4AEE8F9E1111422C889740B24
${requestScope.remoteAddr}
容器将认为remoteAddr是请求范围的属性名,而不是去调用request中的getRemoteAddr方法,所以将出错。然而EL中的pageContext对象却可以调用PageContext类中所有符合规范的getXXX方法。例如,PageContext类中有如下方法:
public abstract ServletRequest getRequest()
则可以通过如下EL调用该方法:
${pageContext.request}
内置对象是EL非常重要的组成部分,共有11个内置对象。值得注意的是,EL中的内置对象和JSP中的内置对象不同,JSP中的内置对象是真正的对象,有具体的类型,可以调用类型中的任意方法。而EL中的内置对象,除了pageContext外,并不与Servlet API中的类型对应,只能使用固定的格式获取相应的内容。pageContext是EL中一个特殊的内置对象,是一个真正的PageContext对象,可以调用符合规范的getXXX方法。
EL中支持五种算术运算符,包括:+,实现加法运算;-,实现减法运算;*,实现乘法运算;/或div,实现除法运算;%或mod,实现求模运算。代码如下所示:
${19+2}
${19-2}
${19*2}
${19/2}
${19%2}
EL中有6种比较运算符,可以对值进行比较,返回值为true或fasle。
① = = 或eq:表示等于。
② != 或ne:表示不等于。
③ < 或lt:表示小于。
④ > 或gt:表示大于。
⑤ <= 或le:表示小于等于。
⑥ >= 或ge:表示大于等于。
EL中提供了3个逻辑运算符,可以对boolean类型的值进行运算,返回值为true或false。
① &&或and:表示交集,两个值都是true才返回true。
② ||或or:表示并集,两个值只要有一个是true,即返回true。
③ !或not:表示非。
假设在testELOperator.jsp中有如下代码:
${param.month==7&¶m.day==4}
${param.month==7||param.day==4}
${!(param.month==7)}
使用URL http://localhost:8080/testELOperator.jsp?month=7&day=6访问该JSP,结果如下:
false
true
false
EL中除了有上面学习的算术、比较、逻辑运算符外,还有三种其他运算符。
① empty运算符:判断值是否为null,如果是null,返回true,否则返回false。
② 关系运算符?::${A?B:C},如果A为true,则执行B;如果A为false,则执行C。
③ ()运算符:通过()可改变优先级。
假设在testELOperator.jsp中有如下代码:
${empty param.day}
${param.year==2010?param.month+1:param.day+1}
${param.day}
通过URL http://localhost:8080/testELOperator.jsp?year=2009&month=7&day=6访问该JSP文件,结果如下:
false 7 6
EL中提供.和[]两种操作符来获得数据,下面的两行代码等同:
${requestScope.cust2.custname}
${requestScope["cust2"]["custname"]}
然而,在下面这些情况下,却只能使用[]。
① 数组或集合的索引,只能使用[],不能用.。
${paramValues.hobbies[0]}
${requestScope.list[1].custname}
② 属性值中包括-或者.等非字母或数字的字符,只能使用[],不能用.。
不合法的EL:${param.user_name}
合法的EL:${param["user_name"]}
值得注意的是,常量可以使用""引用,也可以使用单引号' '引用。
③ 属性值不是常量,而是变量。例如,paramName是变量,其具体值可能是name,可能是date等。
不合法的EL:${param.paramName}
合法的EL:${param[paramName]}
EL除了可以方便地获取数据外,还可以方便地进行数据类型转换,如:
${param.count+10}
param.count获取的是请求参数的值,为String类型,可以直接与整数10进行数学运算,不需要类型转换,EL自动对其进行了类型转换。
表达式中对null往往是直接显示,或者抛出空指针异常,代码如下所示:
<%=request.getParameter("name")%>
如果不存在name请求参数,则在页面中显示null。而如果使用EL获得name值,代码如下所示:
${param.name}
如果不存在name请求参数,页面中则什么也不显示。
又如,通过表达式显示请求属性的属性值:
<%=((Customer)request.getAttribute("cust2")).getCustname()%>
如果请求中不存在cust2属性,则抛出空指针异常。而如果使用EL:
${requestScope.cust2.custname}
如果请求中不存在cust2属性,则页面中什么也不显示。