首页 > 代码库 > 一步一步学jsp--EL表达式(二)

一步一步学jsp--EL表达式(二)

        前面已经了解了JSP的一些内容:jsp指令元素,jsp脚本元素,jsp标签,jsp页面注释,jsp内置对象。本篇来学些下EL表达式,主要学习下el表达式的语法以及其用处

1、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。

2、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 = http://www.mamicode.com/${cookie.JSESSIONID.value }
>
运行结果如下:

---------------------------------------------

cookie = {JSESSIONID=javax.servlet.http.Cookie@739136}
cookie.JSESSIONID = javax.servlet.http.Cookie@739136
cookie.JSESSIONID.name = JSESSIONID
cookie.JSESSIONID.value = http://www.mamicode.com/2A7F6CADF34F099D91AF0A80C2582D29
cookie.JSESSIONID.value = http://www.mamicode.com/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 ? "未登录" : "登录了" }

3、EL Function

      EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。 EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。语法:${prefix:method(params)}EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能

EL表达式保留关键字:

技术分享

关于更多EL函数的内容,请参见下一篇文章

一步一步学jsp--EL表达式(二)