前面已经了解了JSP的一些内容:jsp指令元素,jsp脚本元素,jsp标签,jsp页面注释,jsp内置对象。本篇来学些下EL表达式,主要学习下el表达式的语法以及其用处。
EL表达式的全名为Expression Language。EL主要用于:
- 获取数据:
EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问Set集合、访问map集合、访问数组)
- 执行运算:
利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。
- 获取web开发常用对象
EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
- 调用Java方法
EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。(此部分的内容会在下章的JSTL中进行介绍)
- 使用条件
JSP2.0之后,EL已经正式纳入并成为标准规范之一。只要支持Servlet2.4/JSP2.0的Container,都可以在JSP网页中直接使用EL。
EL表达式获取数据的语法: ${expression}, EL表达式在执行时会调用pageContext.findAttribute方法,用标识符为关键字,分别从page,request,session,application四个域中查找对应的对象,找到则返回对象的对象,找不到则返回""(注意,这里返回的不是null,而是空串)。
列如:
<% String nullStr = null; String name = "Riccio Zhang"; pageContext.setAttribute("nullStr", nullStr); pageContext.setAttribute("name", name); %> nullStr = ${nullStr}<br/> name = ${name}运行结果如下:-----------------------------
nullStr =
name = Riccio Zhang-----------------------------
对应的翻译的java代码如下:
String nullStr = null; String name = "Riccio Zhang"; pageContext.setAttribute("nullStr", nullStr); pageContext.setAttribute("name", name); out.write("\r\n"); out.write("\tnullStr = "); out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${nullStr}", java.lang.String.class, (PageContext)_jspx_page_context, null, false)); out.write("<br/>\r\n"); out.write("\tname = "); out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${name}", java.lang.String.class, (PageContext)_jspx_page_context, null, false));EL表达式是通过org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate进行解析的,具体是怎样解析的可以去看看源码。
在jsp中EL表达式可以通过page指令来指定是否忽略EL表达式,例如:<%@ page isELIgnored="false"%>,指定不忽略EL表达式,如果设置为true,则会忽略EL表达式。除此之外还可以采用转义的方式来让浏览器将EL表达式原样输出,例如: \${name}
2.1、获取web开发常用对象
EL表达式语言定义了11个隐含对象,使用这些隐含对象可以很方便的获取web开发中常用的一些对象,并获取这些对象的数据。
语法:${隐式对象的名称},获取对象的引用。
EL表达式的11个隐式对象如下表:
隐含对象名称
说 明
pageContext
对应于JSP页面中的pageContext对象(注意:取的是pageContext对象。)
pageScope
代表page域中用于保存属性的Map对象
requestScope
代表request域中用于保存属性的Map对象
sessionScope
代表session域中用于保存属性的Map对象
applicationScope
代表application域中用于保存属性的Map对象
param
表示一个保存了所有请求参数的Map对象
paramValues
表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]
header
表示一个保存了所有http请求头字段的Map对象
headerValues
同上,返回string[]数组。注意:如果头里面有“-” 例Accept-Encoding,则headerValues[“Accept-Encoding”]
cookie
表示一个保存了所有cookie的Map对象
initParam
表示一个保存了所有web应用初始化参数的map对象
pageContext使用,el表达式可以调用get[is]类型的方法,并且方法没有参数。还可以连写
${pageContext.request.queryString}取得请求的参数字符串
${pageContext.request.requestURL}取得请求的URL,但不包含请求参数字符串
${pageContext.request.contextPath}取得服务的web application的名称
${pageContext.request.method}取得HTTP的方法(GET、POST)
${pageContext.request.protocol}取得使用的协议(HTTP/1.1、HTTP/1.0)
${pageContext.request.remoteUser}取得用户名称
${pageContext.request.remoteAddr}取得用户的IP地址
${pageContext.session.new}判断session是否为新的,所谓新的session,表示刚由server产生而client尚未使用
${pageContext.session.id}取得session的ID
${pageContext.servletContext.serverInfo}取得主机端的服务信息注意:pageContext有jsp其它8个对象的引用,也就是只有能拿到pageContext对象就可以拿到其它的对象。
4个域:
<% pageContext.setAttribute("msg", "page_msg", PageContext.PAGE_SCOPE); pageContext.setAttribute("msg", "request_msg", PageContext.REQUEST_SCOPE); pageContext.setAttribute("msg", "session_msg", PageContext.SESSION_SCOPE); pageContext.setAttribute("msg", "application_msg", PageContext.APPLICATION_SCOPE); %> 获取数据:<br/> 直接获取:${msg}<br/> page: ${pageScope.msg}<br/> page: ${requestScope.msg}<br/> page: ${sessionScope.msg}<br/> page: ${applicationScope.msg}<br/>
运行结果如下:--------------------------------------------
获取数据:
直接获取:page_msg
page: page_msg
page: request_msg
page: session_msg
page: application_msg--------------------------------------------
请求参数:
name = ${param.name }<br/> paramValues = ${paramValues }<br/> paramValues.name = ${paramValues.name}<br/>
在浏览器地址栏输入如下地址时:http://localhost:8080/EL/el.jsp?name=RiccioZhang&age=12&address=GZ
运行结果如下:
---------------------------------------------
name = RiccioZhang
paramValues = {address=[Ljava.lang.String;@105a248, name=[Ljava.lang.String;@e133da, age=[Ljava.lang.String;@1135cd9}
paramValues.name = [Ljava.lang.String;@34cdfc---------------------------------------------
可见在param对应的Map中保存的value是一个字符串,而在paramValues保存的是一个String[]
请求头信息:
获取请求头信息:<br/> header = ${header }<br/> headerValues = ${headerValues }<br/> header.accept = ${header.accept }<br/> headerValues.accept = ${headerValues.accept}<br/> header["user-agent"] = ${header["user-agent"] }<br/> headerValues["user-agent"] = ${headerValues["user-agent"] }<br/>运行结果如下:---------------------------------------------
header = {cache-control=max-age=0, cookie=JSESSIONID=2A7F6CADF34F099D91AF0A80C2582D29, connection=keep-alive, accept-language=zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3, host=localhost:8080, accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, user-agent=Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0, accept-encoding=gzip, deflate}
headerValues = {cache-control=[Ljava.lang.String;@16999c8, cookie=[Ljava.lang.String;@1ef3d12, connection=[Ljava.lang.String;@1927504, accept-language=[Ljava.lang.String;@408893, host=[Ljava.lang.String;@c6a26b, accept=[Ljava.lang.String;@d11f32, user-agent=[Ljava.lang.String;@157457b, accept-encoding=[Ljava.lang.String;@92a78b}
header.accept = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
headerValues.accept = [Ljava.lang.String;@35c41b
header["user-agent"] = Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
headerValues["user-agent"] = [Ljava.lang.String;@1ddcac5
---------------------------------------------
关于上面有几点需要说明:
- param保存的Map对应的value是一个String,而paramValues保存的则是一个String[]。
- 对于一些的特殊的头,比如user-agent,假如直接写成${header.user-agent}会解析错误,因为"-"相当于是个减号,对于这些特许的数据需要这样来获取${header["user-agent"]}, 也可以把双引号写成当引号。不光只是header,在EL表达式中对于这些特殊的符号都应该采用上述的办法。
- 头部信息是不区分大小写的,例如${header.accept}和${header.ACCEPT}是等价的。
cookie:
cookie = ${cookie }<br/> cookie.JSESSIONID = ${cookie.JSESSIONID }<br/> cookie.JSESSIONID.name = ${cookie.JSESSIONID.name }<br/> cookie.JSESSIONID.value = ${cookie.JSESSIONID.value }<br/> cookie.JSESSIONID.value = ${cookie.JSESSIONID.value }<br/> cookie.JSESSIONID.maxAge = ${cookie.JSESSIONID.maxAge }<br/> cookie.JSESSIONID.path = ${cookie.JSESSIONID.path }<br/>
运行结果如下:---------------------------------------------
cookie = {JSESSIONID=javax.servlet.http.Cookie@739136}
cookie.JSESSIONID = javax.servlet.http.Cookie@739136
cookie.JSESSIONID.name = JSESSIONID
cookie.JSESSIONID.value = 2A7F6CADF34F099D91AF0A80C2582D29
cookie.JSESSIONID.value = 2A7F6CADF34F099D91AF0A80C2582D29
cookie.JSESSIONID.maxAge = -1
cookie.JSESSIONID.path =
---------------------------------------------
可以看出上面获取到的是Cookie对象,而且Cookie的名字是区分大小写的(这点要注意)。
initParam:
initParam = ${initParam }<br/> initParam.name = ${initParam.name }<br/> initParam.age = ${initParam.age }<br/>在web.xml文件中配置如下:
<context-param> <param-name>name</param-name> <param-value>RiccioZhang</param-value> </context-param> <context-param> <param-name>age</param-name> <param-value>12</param-value> </context-param>运行结果如下
---------------------------------------------
initParam = {age=12, name=RiccioZhang}
initParam.name = RiccioZhang
initParam.age = 12---------------------------------------------
2.2、执行运算
- 语法:${运算表达式},EL表达式支持如下运算符:算术运算符、关系运算符、逻辑运算符、empty运算符、二元运算符。
- EL提供.和[]两种运算符来获取数据
例如:${sessionScope.book.title} 获得book对象的title值等价 ${sessionScope.book["title"]}
- .和[]也可以同时混合使用
例如:${sessionScope.bookList[0].title} 获得bookList第一本书籍的title值等价 ${sessionScope.bookList[0]["title"]}
- 当属性名称包含一些特殊字符,如.或-等非字母或数字的符号时,需使用[]
例如:${sessionScope["bo-ok"].title}
- 当获得方法是动态获取的,就一定要使用[]
例如:
<% request.setAttribute("name", "zq"); request.setAttribute("zq", "RiccioZhang"); %> ${requestScope[requestScope.name] }2.2.1、算术运算符
注意: + 不能用来拼接字符串,只能用来数值相加。
2.2.2 关系运算符
注意:避免与jsp发生冲突,尽量的使用字符形式来代替符号形式,例如用ge代替>=
2.2.3 逻辑运算符
2.2.4 其它
- empty运算符,检查对象是否为空,如果为""(空字符串)也会返回true, 例如:
<% Object o = new Object(); pageContext.setAttribute("o", o); %> \${empty o } = ${empty o }<br/> \${empty a } = ${empty a }<br/>
结果如下:---------------------------------------------
${empty o } = false
${empty a } = true
---------------------------------------------
- 二元运算符,例如:
\${user == null ? "未登录" : "登录了" } = ${user == null ? "未登录" : "登录了" }
EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。 EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。语法:${prefix:method(params)}。EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。
EL表达式保留关键字:
关于更多EL函数的内容,请参见下一篇文章。