前几篇文章,我们学会了JSP的相关知识,以及Sun公司为了增强JSP的功能,不遗余力的往JSP的武器库中添加装备,如我们之前学的指令、脚本元素、动作元素、隐式对象,域对象。不过仅仅是这些么,NoNoNo,今天要讲的EL表达式,与下一文中要讲的JSTL,也是武器库中比较耀眼的两把利器。今天我们就来学习下EL表达式。
文章目录
1.EL的概念
在JSP开发中,域对象对前后端数据的传输起了很大的作用,可以让数据不必真正的到浏览器上在进行处理(而是在服务器端将数据输出到页面上,浏览器只负责展示后端返回的HTML),但是呢,不可避免的,要在JSP页面中写上许多的Java代码来从域对象中获取数据,如下代码所示:
<%
if(session.getAttribute("userName") != null){
out.print("<h1>欢迎:" + session.getAttribute("userName") + ",恭喜登录成功</h1>");
} else{
out.print("<h1>登录已过期,请重新登录</h1>");
out.print("<a href='./Login.jsp'>重新登录</a>");
}
%>
Java脚本元素中获取值或者定义的变量,也只能在Java脚本元素中使用,这也就导致,如果页面上从域对象获取了较多的数据,那么JSP中会嵌入许多的Java代码块,虽然不影响功能的实现,但是让页面变得复杂,增加开发与维护难度。
问题已经抛出来了,那要如何解决呢?
今日份主角–EL闪亮登场。EL全称是Expression Language,也可以称之为EL表达式,在JSP2.0规范后开始可以使用。EL表达式是一种简单的数据访问语言。既然是数据访问语言,那么其访问哪里的数据?联想我们刚才抛出的问题,这里EL访问的主要对象是JSP域对象中的数据。
EL表达式的使用非常简单,如下所示:
${表达式}
不过表达式需要遵循EL表达的语法。不过这里大家不用担心,既然是JSP推出来为了简化JSP页面开发的,其学习成本自然不会高,其语法基本与Java无异。下面我们一起来看下。
2.EL语法
2.1 EL中的标识符
在EL表达式中,经常需要使用一些符号来标记变量、函数名称等,我们可以称之为标识符,其命名的语法规范和Java中变量的命名规则基本相同,需要遵循以下规范:
- 不能以数字开头;
- 不能是EL中的保留字;
- 不能是EL中的隐式对象;
- 不能包含单引号(’)、双引号(")、减号(-)和正斜线等特殊字符;
2.2 EL中的保留字
EL也和其他语言一样,定义了一些保留字,具体如下:
EL表达式的保留字基本上都是运算符,在使用EL时可以使用保留字来代替运算符,比如eq
与==
。
2.3 EL中的变量
EL中的变量是一个基本的存储单元,EL表达式可以将${}
的变量映射到具体的对象上,或者域对象中绑定的属性上。EL表达式中使用变量是无须事先定义,直接使用即可,一个简单的示例如下:
${ product = 1 }
<h1>product的值为:${product}</h1>
需要注意的是,EL中使用的变量,都是映射到JSP的域对象中的,如果直接使用,默认是将变量绑定到page域上的,我们可以看下如下例子:
${ product = 1 }
<h1>通过获取的product的值为:${product}</h1>
<%
out.println("<h1>通过Page域获取的product的值为:" +
pageContext.getAttribute("product", pageContext.PAGE_SCOPE) + "</h1>");
%>
运行结果如下所示,我们可以很轻易的验证上面的话。
2.4 EL中运算符
EL表达式中支持简单的运算,比如:加(+)、减(-)、乘(*)、除(/)等。其操作也和Java没什么不同,我们简单的进行下介绍。
- 点运算符(.):用与访问JSP页面中的某些属性,如:
${product.id}
; - 方括号运算符([]):与点运算符功能类似,一样可以访问对象的属性,不过其还可以访问集合或数组对应下标中的值,其使用示例如下:
${product[id]}
、${productList[0]}
、${product.detailList[0]}
; - 算术运算符:加(+)、减(-)、乘(*)、除(/或div)、取余(%或mod),其用法很简单,如:
${1 + 1}
; - 比较运算符:等于(==或eq)、不等于(!=或ne)、小于(<或lt)、大于(>或gt)、小于等于(<=或le)、大于等于(>=或ge),其用法示例如下:
${count > 10}
、${count gt 10}
; - 逻辑运算符:与(&&或and)、或(||或or)、非(!或not);
- empty运算符:empty是EL的保留字,其功能是判断变量是否为空,功能类似于isEmpty(),其用法如下:
${empty product}
,需要注意的是,如果product不存在、值为null、或者product为集合且其size为0,这三种情况,${empty product}
的值为true; - 条件运算符:唯一的三元运算符,其用法如下:
${A?B:C}
; - "()"运算符:改变原本表达式中运算的优先级,如
${1*(2+3)}
;
3.EL中的隐式对象
EL中也提供了隐式对象,且其数量还要对于JSP的隐式对象,具体如下所示:
其中的pageContext对象,可以用于获取其他的隐式对象,其用法可以参考JSP的隐式对象pageContext;pageScope、requestScope、sessionScope、applicationScope是对应着JSP中的四大域对象;param、paramValues、header、headerValues、cookie均是从request中获取对应的数据;initParam可用于获取Web应用的初始化信息。
3.1 pageContext对象
我们可以使用pageContext来获取JSP中的隐式对象,并且在EL表达是中获取其中的值,有如下代码,我们可以可以通过pageContext获取到request对象,从而获取到Servlet的上下文,即"/projectName
"
<h1>通过pageContext获取的项目路径:${pageContext.request.contextPath}</h1>
<h1>Content-Type响应头:${pageContext.response.contentType}</h1>
<h1>服务器信息:${pageContext.servletContext.serverInfo}</h1>
<h1>Servlet注册名:${pageContext.servletConfig.servletName}</h1>
其运行结果如下所示,因为所有的JSP页面是由Tomcat提供的jspServlet处理的,所以其注册名称为jsp。
3.2 Web域相关对象
我们知道,JSP有四大域对象,EL表达式设计的目标之一就是可以方便的从JSP的域对象中获取数据,因此,EL中也有与之相对应的隐式对象,分别如下:
- page域:pageScope对象,
${pageScope.product}
等价于pageContext.getAttribute("product", pageContext.PAGE_SCOPE);
- request域:requestScope对象,
${requestScope.product}
- session域:sessoinScope对象,
${sessionScope.product}
- application域:applicationScope对象,
${applicationScope.product}
。
需要注意的一点是,${product}
功能等同于pageContext.getAttribute("product")
,即可以不用指定域对象,获取对象时,按照域对象的大小范围依次去查找属性(${pageScope.product}
–>${requestScope.product}
–>${sessionScope.product}
–>${applicationScope.product}
),如果查到则停止查找且返回对应的值。
我们通过一个页面来演示下通过EL的隐式对象来获取数据,页面代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head></head>
<body>
<%
pageContext.setAttribute("userName", "lizishu");
request.setAttribute("bookName", "Java Web");
session.setAttribute("userName", "lizishudd");
application.setAttribute("bookName", "Java 基础");
%>
<h1>表达式\${pageScope.userName}的值为:${pageScope.userName}</h1>
<h1>表达式\${requestScope.bookName}的值为:${requestScope.bookName}</h1>
<h1>表达式\${sessionScope.userName}的值为:${sessionScope.userName}</h1>
<h1>表达式\${applicationScope.bookName}的值为:${applicationScope.bookName} </h1>
<!-- 等价于pageContext.getAttribute("userName") -->
<h1>表达式\${userName}的值为:${userName}</h1>
</body>
</html>
页面运行结果如下图所示:
3.3 客户端请求参数相关对象
在JSP页面中,为了获取客户端传递的请求参数,EL提供了param、cookie等隐式对象,让我们可以简单直接的获取对应的值,而不必自己写许多代码。
这里,为了演示param、paramValues对象的使用,我们新建一个param.jsp页面,页面代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<html>
<head>
<title>EL之param测试</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/param.jsp">
姓名:<input type="text" name="userName"><br />
爱好:<input type="checkbox" name="hobby" value="篮球">篮球
<input type="checkbox" name="hobby" value="羽毛球">羽毛球
<input type="checkbox" name="hobby" value="足球">足球
<br/>
<input type="submit" value="提交" />
<hr>
姓名:${param.userName}<br />
爱好:${paramValues}<br />
第一个爱好:${paramValues.hobby[0]}<br />
</form>
</body>
</html>
页面上随机输入部分数据后,点击提交按钮,将form中的数据提交到本页面中,页面效果如下:
hader、cookie对象的使用也很简单,我们看如下示例代码:
<!-- 获取Request Headers的host头 -->
${header.host}
<!-- 获取name为userName的Cookie对象 -->
${cookie.userName}
<!-- 获取name为userName的Cookie对象的name、value -->
${cookie.userName.name}
${cookie.userName.value}
4.EL的常用示例
这里的用法在上面都有提及,因此这里只是简单的演示,具体细节可以向前看。
<!-- 从域对象中获取数据 -->
${product}
${pageScope.product}
${requestScope.product}
${sessionScope.product}
${applicationScope.product}
<!-- 获取项目名,一般用于绝对路径的方式跳转或获取资源 -->
${pageContext.request.servletPath}
<!-- 获取对象的属性,列表中的值 -->
${product.id}
${product.detailList[0]}
<!-- 设置pooduct的id值 -->
${prodcut.id = 1 }
<!-- 判断product是否为null || "" || size==0 -->
${empty prodcut }
<!-- 向js函数中传参 -->
<button onClick="lookDetail('${product.id}')">查看详情</button>
<!-- 获取requst中的请求参数 -->
${param.userName}
${paramValues.hobby[0]}
<!-- 获取客户端cookie,其中cookieName即为字面含义,如:JSESSIONID -->
${cookie.cookieName.name }
${cookie.cookieName.value }
5.总结
EL表达式到这里算是讲完了,不过精彩还在继续。EL表达式与JSTL的结合,在很大的程度上简化了JSP页面的开发难度,让后端程序员可以使用非常低的成本(学习成本、时间成本)可以完成前端页面的开发。因此,下篇文章见咯。
又到了分隔线以下,本文到此就结束了,本文内容全部都是由博主自己进行整理并结合自身的理解进行总结,如果有什么错误,还请批评指正。
Java web这一专栏会是一个系列博客,喜欢的话可以持续关注,如果本文对你有所帮助,还请还请点赞、评论加关注。
有任何疑问,可以评论区留言。