ELJSTL.docx
《ELJSTL.docx》由会员分享,可在线阅读,更多相关《ELJSTL.docx(141页珍藏版)》请在冰豆网上搜索。
ELJSTL
6-1EL简介
JSP2.0技术手册
第六章ExpressionLanguage
6-1EL简介
EL全名为ExpressionLanguage,它原本是JSTL1.0为方便存取数据所自定义的语言。
当时EL
只能在JSTL标签中使用,如下:
outvalue="${3+7}">
程序执行结果为10。
但是你却不能直接在JSP网页中使用:
Hi!
${username}
到了JSP2.0之后,EL已经正式纳入成为标准规范之一。
因此,只要是支持Servlet2.4/JSP
2.0的Container,就都可以在JSP网页中直接使用EL了。
除了JSP2.0建议使用EL之外,JavaServerFaces(JSR-127)也考虑将EL纳入规范,由此
可知,EL如今已经是一项成熟、标准的技术。
注意
假若您所用的Container只支持Servlet2.3/JSP1.2,如:
Tomcat4.1.29,您就不能在
JSP网页中直接使用EL,必须安装支持Servlet2.4/JSP2.0的Container。
6-2EL语法
EL语法很简单,它最大的特点就是使用上很方便。
接下来介绍EL主要的语法结构:
${sessionScope.user.sex}
所有EL都是以${为起始、以}为结尾的。
上述EL范例的意思是:
从Session的范围中,取得
用户的性别。
假若依照之前JSPScriptlet的写法如下:
Useruser=(User)session.getAttribute("user");
Stringsex=user.getSex();
Java爱好者制作
JSP2.0技术手册
两者相比较之下,可以发现EL的语法比传统JSPScriptlet更为方便、简洁。
6-2-1.与[]运算符
EL提供.和[]两种运算符来存取数据。
下列两者所代表的意思是一样的:
${sessionScope.user.sex}
等于
${sessionScope.user["sex"]}
.和[]也可以同时混合使用,如下:
${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:
Java爱好者制作
${expr-a[expr-b]}
JSP2.0技术手册
(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-2EL变量
EL存取变量数据的方法很简单,例如:
${username}。
它的意思是取出某一范围中名称为username
的变量。
因为我们并没有指定哪一个范围的username,所以它的默认值会先从Page范围找,假如
找不到,再依序到Request、Session、Application范围。
假如途中找到username,就直接回传,
不再继续找下去,但是假如全部的范围都没有找到时,就回传null(见表6-1):
Java爱好者制作
属性范围
Page
Request
Session
Application
JSP2.0技术手册
表6-1
在EL中的名称
PageScope
RequestScope
SessionScope
ApplicationScope
自动搜索顺序
我们也可以指定要取出哪一个范围的变量(见表6-2):
表6-2
范例
说明
${pageScope.username}
${requestScope.username}
${sessionScope.username}
${applicationScope.username}
取出Page范围的username变量
取出Request范围的username变量
取出Session范围的username变量
取出Application范围的username变量
其中,pageScope、requestScope、sessionScope和applicationScope都是EL的隐含对象,由
它们的名称可以很容易猜出它们所代表的意思,例如:
${sessionScope.username}是取出Session
范围的username变量。
这种写法是不是比之前JSP的写法:
Stringusername=(String)session.getAttribute("username");
容易、简洁许多。
有关EL隐含对象在6-3节中有更详细的介绍。
6-2-3自动转变类型
EL除了提供方便存取变量的语法之外,它另外一个方便的功能就是:
自动转变类型,我们来看
下面这个范例:
${param.count+20}
假若窗体传来count的值为10时,那么上面的结果为30。
之前没接触过JSP的读者可能会认为
上面的例子是理所当然的,但是在JSP1.2之中不能这样做,原因是从窗体所传来的值,它们的类
型一律是String,所以当你接收之后,必须再将它转为其他类型,如:
int、float等等,然后才能
执行一些数学运算,下面是之前的做法:
Stringstr_count=request.getParameter("count");
Java爱好者制作
JSP2.0技术手册
intcount=Integer.parseInt(str_count);
count=count+20;
接下来再详细说明EL类型转换的规则:
(1)将A转为String类型
●假若A为String时:
回传A
●否则,当A为null时:
回传""
●否则,当A.toString()产生异常时:
错误!
●否则,回传A.toString()
(2)将A转为Number类型的N
●假若A为null或""时:
回传0
●假若A为Character时:
将A转为newShort((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时:
回传newByte(A.byteValue())
·假若N为Short时:
回传newShort(A.shortValue())
·假若N为Integer时:
回传newInteger(A.intValue())
Java爱好者制作
JSP2.0技术手册
·假若N为Long时:
回传newLong(A.longValue())
·假若N为Float时:
回传newFloat(A.floatValue())
·假若N为Double时:
回传newDouble(A.doubleValue())
·否则,错误!
●假若A为String时:
·假若N是BigDecimal时:
·假若newBigDecimal(A)产生异常时:
错误!
·否则,回传newBigDecimal(A)
·假若N是BigInteger时:
·假若newBigInteger(A)产生异常时:
错误!
·否则,回传newBigInteger(A)
·假若N.valueOf(A)产生异常时:
错误!
·否则,回传N.valueOf(A)
●否则,错误!
(3)将A转为Character类型
●假若A为null或""时:
回传(char)0
●假若A为Character时:
回传A
●假若A为Boolean时:
错误!
●假若A为Number时:
转换为Short后,然后回传Character
●假若A为String时:
回传A.charAt(0)
●否则,错误!
(4)将A转为Boolean类型
Java爱好者制作
JSP2.0技术手册
●假若A为null或""时:
回传false
●否则,假若A为Boolean时:
回传A
●否则,假若A为String,且Boolean.valueOf(A)没有产生异常时:
回传Boolean.valueOf(A)
●否则,错误!
6-2-4EL保留字
EL的保留字如表6-3:
表6-3
And
Or
No
instanceof
eq
ne
lt
empty
gt
le
ge
div
true
false
null
mod
所谓保留字的意思是指变量在命名时,应该避开上述的名字,以免程序编译时发生错误。
6-3EL隐含对象
笔者在“第五章:
隐含对象(ImplicitObject)”中,曾经介绍过9个JSP隐含对象,而EL本
身也有自己的隐含对象。
EL隐含对象总共有11个(见表6-4):
表6-4
隐含对象
类
型
说明
PageContext
javax.servlet.ServletContext表示此JSP的PageContext
PageScope
java.util.Map
取得Page范围的属性名称所对应的值
取得Request范围的属性名称所对应
RequestScopejava.util.Map
sessionScopejava.util.Map
applicationScopejava.util.Map
的值
取得Session范围的属性名称所对应
的值
取得Application范围的属性名称所
对应的值
如同
param
隐含对象
java.util.Map
类型
续表
ServletRequest.getParameter(String
name)。
回传String类型的值
说明
paramValuesjava.util.Map
如同
Java爱好者制作
隐含对象
JSP2.0技术手册
类型
说
明
header
java.util.Map
ServletRequest.getParameterValues(String
name)。
回传String[]类型的值
如同ServletRequest.getHeader(String
name)。
回传String类型的值
如同ServletRequest.getHeaders(String
headerValuesjava.util.Map
name)。
回传String[]类型的值
cookie
initParam
java.util.Map
java.util.Map
如同HttpServletRequest.getCookies()
如同
ServletContext.getInitParameter(String
name)。
回传String类型的值
这11个隐含对象(ImplicitObject),笔者将它分成三类:
1.与范围有关的隐含对象
applicationScope
sessionScope
requestScope
pageScope
2.与输入有关的隐含对象
param
paramValues
3.其他隐含对象
cookie
header
headerValues
initParam
pageContext
接下来笔者会依照上面的分类顺序,为读者介绍这些隐含对象。
6-3-1属性(Attribute)与范围(Scope)
Java爱好者制作
JSP2.0技术手册
与范围有关的EL隐含对象包含以下四个:
pageScope、requestScope、sessionScope和
applicationScope,它们基本上就和JSP的pageContext、request、session和application一样,
所以笔者在这里只稍略说明。
不过必须注意的是,这四个隐含对象只能用来取得范围属性值,即JSP
中的getAttribute(Stringname),却不能取得其他相关信息,例如:
JSP中的request对象除可以存
取属性之外,还可以取得用户的请求参数或表头信息等等。
但是在EL中,它就只能单纯用来取得对应
范围的属性值,例如:
我们要在session中储存一个属性,它的名称为username,在JSP中使用
session.getAttribute("username")来取得username的值,但是在EL中,则是使用
${sessionScope.username}来取得其值的。
接下来分别对这四个隐含对象做简短的说明:
●pageScope
范围和JSP的Page相同,也就是单单一页JSPPage的范围(Scope)。
●requestScope
范围和JSP的Request相同,requestScope的范围是指从一个JSP网页请求到另一个JSP网页
请求之间,随后此属性就会失效。
●sessionScope
范围和JSPScope中的session相同,它的属性范围就是用户持续在服务器连接的时间。
●applicationScope
范围和JSPScope中的application相同,它的属性范围是从服务器一开始执行服务,到服务
器关闭为止。
6-3-2与输入有关的隐含对象
与输入有关的隐含对象有两个:
param和paramValues,它们是EL中比较特别的隐含对象。
一般
而言,我们在取得用户的请求参数时,可以利用下列方法:
request.getParameter(Stringname)
request.getParameterValues(Stringname)
在EL中则可以使用param和paramValues两者来取得数据。
Java爱好者制作
${param.name}
${paramValues.name}
JSP2.0技术手册
这里param的功能和request.getParameter(Stringname)相同,而paramValues和
request.getParameterValues(Stringname)相同。
如果用户填了一个表格,表格名称为username,则我们
就可以使用${param.username}来取得用户填入的值。
为了让读者更加了解param和paramValues隐含对象的使用,再来看下面这个范例。
此范例共
有两个文件,分别为给用户输入值用的Param.html和显示出用户所传之值的Param.jsp。
Param.html
CH6-Param.html
EL隐含对象param、paramValues
姓名:
密码:
性别:
男
女
年龄:
Java爱好者制作
JSP2.0技术手册
10-20
20-30
30-40
40-50
兴趣:
看书
玩游戏
旅游
听音乐
看电视
Java爱好者制作
JSP2.0技术手册
Param.html的执行结果如图6-1所示。
当我们把窗体填好后按下传送钮,它将会把信息传送到
Param.jsp做处理。
图6-1Param.html的执行结果,并填入信息
接下来,Param.jsp接收由Param.html传来的信息,并且将它显示出来:
Param.jsp
<%@pagecontentType="text/html;charset=GB2312"%>
<%@taglibprefix="c"uri="%>
<%@taglibprefix="fmt"uri="%>
CH6-Param.jsp
EL隐含对象param、paramValues
Ja