目录
一、介绍
- 由Java技术开发一个jar包。
- 作用降低 JSP 文件开发时Java命令开发强度。
【注】Tomcat服务器本身自带了EL工具包(Tomcat安装地址/lib/el-api.jar)。
EL表达式——作用域对象别名
作用域 | JSP作用域对象 | EL表达式作用域对象别名 |
全局作用域对象 | ServletContext application | ${applicationScope.共享数据名} |
会话作用域对象 | HttpSession session | ${sessionScope.共享数据名} |
请求作用域对象 | HttpServletRequest request | ${requestScope.共享数据名} |
当前页作用域对象 | PageContext pageContext | ${pageScope.共享数据名} |
【注意】:PageContext pageContext:当前页作用域对象,这是JSP文件独有的作用域对象。Servlet中不存在在当前页作用域对象存放的共享数据仅能在当前JSP文件中使用,不能共享给其他Servlet或则其他JSP文件真实开发过程,主要用于JSTL标签与JSP文件之间数据共享。
数据共享如下:JSTL -------> pageContext(数据) ----> JSP
EL表达式
1.命令格式:
${作用域对象别名.共享数据}
【注意】EL 提供 . 和 [ ] 两种运算符来导航数据。下列两者所代表的意思是一样的:
${sessionScope.user.sex}等于${sessionScope.user["sex"]}
2.命令作用:
1)EL表达式是EL工具包提供一种特殊命令格式【表达式命令格式】
2)EL表达式在JSP文件上使用
3)负责在JSP文件上从作用域对象读取指定的共享数据并输出到响应体
Servlet类中给作用域对象中添加信息
ServletContext application = request.getServletContext();
HttpSession session = request.getSession();
application.setAttribute("sid", 110);
session.setAttribute("sname", "mike");
request.setAttribute("home", "三里屯");
转发到一个JSP显示页面上
编号:${applicationScope.sid}<br/>
姓名:${sessionScope.sname}<br/>
地址:${requestScope.home}
显示结果
Id:110
姓名:mike
地址:三里屯
【注意】:EL表达式统一都有一个特点,没有取到任何数据则输出“空字符串”,统一都对空值进行了预处理。
EL表达式将引用对象属性写入到响应体
1.命令格式:
${作用域对象别名.共享数据名.属性名}
【注意】当要存取的属性名称中包含一些特殊字符,如. 或 – 等并非字母或数字的符号,就一定要使用 [ ],例如:${user.My-Name },上述是不正确的方式,应当改为:${user["My-Name"] }。
2.命令作用:从作用域对象读取指定共享数据关联的引用对象的属性值。并自动将属性的结果写入到响应体。
3.属性名: 一定要去引用类型属性名完全一致(大小写)。
创建Student类
public class Student {
private Integer sid;
private String sname;
//set get ,一定要有get方法
}
创建Servlet类
Student stu = new Student(20, "mike");
request.setAttribute("key", stu);
跳转到一个JSP显示页面
学员编号:${requestScope.key.sid}<br/>
学员姓名:${requestScope.key.sname}
【注意】:sid来自Student类属性名,大小写完全一致。底层实际上调用了Javabean对象的getSid
()方法,所以一定要有这个方法。
4.EL表达式从集合中获取数据
Servlet类传入前端的数据
List<student> stuList = new ArrayList<>();
stuList.add(...);
request.setAttribute("stuList", stuList);
前端JSP页面获取数据
${stuList}<br/>
${stuList[0]}<br/>
${stuList[0].sid}<br/>
${stuList[0].sname}<br/>
EL表达式简化版
1.命令格式:
${共享数据名}
2.命令作用: EL表达式允许开发人员开发时省略作用域对象别名
3.工作原理:
EL表达式简化版由于没有指定作用域对象,所以在执行时采用【猜】算法
首先到【pageContext】定位共享数据,如果存在直接读取输出并结束执行。
如果在【pageContext】没有定位成功,到【request】定位共享数据,如果存在直接读取输出并结束执行。
如果在【request】没有定位成功,到【session】定位共享数据,如果存在直接读取输出并结束执行。
如果在【session】没有定位成功,到【application】定位共享数据,如果存在直接读取输出并结束执行。
如果在【application】没有定位成功,返回null。
pageContext--->request--->session--->application
4.存在隐患:
容易降低程序执行速度,容易导致数据定位错误。
5.应用场景:
设计目的,就是简化从pageContext读取共享数据并输出难度。
6.EL表达式简化版尽管存在很多隐患,但是在实际开发过程中,开发人员为了节省时间,一般都使用简化版,拒绝使用标准版。如果EL内置范围对象省略的话,恰巧存储在范围中的数据属性名是相同的,此时EL表达式会从最小的范围获取数据(小范围优先级较高)。
在Servlet类中,使用两个作用域对象添加数据
HttpServletRequest request = new HttpServletRequest();
HttpSession session = request.getSession();
session.setAttribute("key", "张三");
request.setAttribute("key", "李四");
跳转到JSP显示页面
标准版EL表达式key的值:${sessionScope.key}<br/>
简化版EL表达式key的值:${key}
结果
标准版EL表达式key的值:张三
简化版EL表达式key的值:李四
分析以下EL表达式的区别
${abc}
解析:上面是从某个范围对象中取数据,name是abc。
${"abc"}
解析:上面是将普通字符串“abc”打印输出到浏览器上。
EL表达式支持运算表达式
1.前提: 在JSP文件有时需要将读取共享数据进行一番运算之后,将运算结果写入到响应体。
2.运算表达式:
1) 数学运算
2) 关系运算: > (gt),>= (ge),== (eq),< (lt), <= (le),!=,可以与括号里的相互替换。
3)逻辑运算: &&,||,!
【注意】关于EL表达式的加法运算,只完成求和,不会做字符串连接
${1 + 1}
${1 + "2"}
${"10" + "20"}
以下程序出现java.lang.NumberFormatException异常
${"abc" + "1"}
【注意】关于EL表达式中 == 调用了equals方法
【重点】运算符empty,判断是否为空,EL认为只要没有就是空
${empty stu}
${empty ""}
${empty null}
【注意】 这里的null还是关键字null,表示空
EL表达式提供内置对象
内置对象除了上面说到的四个作用域对象,还有其他个隐含对象,内置对象:比如param、paramValues、initParam等。
param
1.命令格式:
${param.请求参数名}
2.命令作用: 通过请求对象读取当前请求包中请求参数内容并将请求参数内容写入到响应体。
如url: Http://localhost:8080/myWeb/index.jsp?userName=mike
${param.userName}
可以通过上面param对象,获取参数userName的值mike。
paramValues
1.命令格式:
${paramValues.请求参数名[下标]}
2.命令作用:如果浏览器发送的请求参数是[一个请求参数关联多个值],此时可以通过paramVaues读取请求参数下指定位置的值,并写入到响应体。
如url: http://localhost:8080/myWeb/index_2.jsp?deptNo=10&deptNo=20
${paramValues.deptNo}<br/>
${paramValues.deptNo[0]}<br/>
${paramValues.deptNo[1]}<br/>
可以通过上面paramValues对象,获取多个参数deptNo的值。
initParam
需要在webapp下web.xml中添加初始化参数,用逗号分隔
<context-param>
<param-name>ips</param-name>
<param-value>127.0.0.1,192.168.1.100,192.168.1.3</param-value>
</context-param>
${initParam.ips}
可以获取这些数据。
还有一些其他的内置对象
术语 | 定义 |
param | 将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 ${param . name}相当于 request.getParameter (name)。 |
paramValues | 将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues. name} 相当于 request.getParamterValues(name)。 |
header | 将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header. name} 相当于 request.getHeader(name)。 |
headerValues | 将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 ${headerValues. name} 相当于 request.getHeaderValues(name)。 |
cookie | 将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie. name .value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues. name} 表达式 |
initParam | 将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。 |
附加:base路径
<base href="${pageContext.request.scheme}://${pageContext.request.serverName}:
${pageContext.request.serverPort}${pageContext.request.contextPath}/"/>
EL表达式常见异常
javax.el.PropertyNotFoundException:类型【xxxx】不存在【属性名】既在某个类中没有找到对应的属性,因为EL表达式在读取对象中属性时,通过反射机制调用当前属性对应的get方法得到属性的值,如果当前属性没有声明对应get方法,此时EL表达式认为当前类文件没有这个属性。
EL表达式禁用
在当前JSP文件中禁用EL表达式
<%@ page isELIgnored="true" %>
解析:表示是否禁用EL语言,true表示禁止,false表示不禁止。
在整个项目中禁用EL表达式
webapp下web.xml文件中
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>