EL表达式
概述
- 由Java技术开发一个jar包
- 作用降低JSP文件开发时Java命令开发强度
- Tomcat服务器本身自带了EL工具包(Tomcat安装地址/lib/el-api.jar)
引例
代替响应对象 将Servlet中doGet/doPost的执行结果写入到响应体。
JSP文件主要开发步骤:
<% String value = (String)request.getAttribute("key"); %> <%=value%>
- 从指定的作用域对象读取处理结果。
- 将得到数据进行类型强转。
- 将转换后的数据写入到响应体。
以上开发步骤太繁琐,可以使用EL表达式简化开发步骤。
命令格式
语法:
${作用域对象别名.共享数据名}
命令作用
- 执行时从指定的【作用域对象】中读取指定【共享数据】的内容并自动的写入到响应体。
EL表达式作用域对象别名
属性范围(jstl名称) | EL名称 | 说明 |
---|---|---|
page | PageScope | |
Request | RequestScope | 请求作用域 |
Session | SessionScope | 会话作用域 |
Application | ApplicationScope | 全局作用域 |
**.**与 [ ] 运算符
EL 提供 . 和 [ ] 两种运算符来导航数据。下列两者所代表的意思是一样的:
${sessionScope.user.sex}等于${sessionScope.user["sex"]}
. 和 [ ] 也可以同时混合使用,如下:
${sessionScope.shoppingCart[0].price}
以上两者的差异:
- 当要存取的属性名称中包含一些特殊字符,如.或–等并非字母或数字的符号,就一定要使用 [ ]
<%--错误写法:因为属性名中含有-/--%> ${user.My-Name} <%--正确写法:--%> ${user["My-Name"]}
我们来考虑下列情况:
${sessionScope.user[data]}
此时,data 是一个变量,假若data的值为”sex”时,那上述的例子等于:
${sessionScope.user.sex};
假若data 的值为”name”时,它就等于${sessionScope.user.name},因此,如果要动态取值时,就可以用上述的方法来做,但无法做到动态取值。
简化版EL表达式
命令格式
${作用域对象别名}
工作原理
由于在EL简化版中没有指定作用域对象别名。所以EL表达式采用”猜测算法”,首先到【pageContext】定位共享数据,如果定位成功读取输出并结束执行。
如果在【pageCotnext】没有找到共享数据,到【request】定位共享数据,如果定位成功读取输出并结束执行。
如果在【request】没有找到共享数据,到【session】定位共享数据,如果定位成功读取输出并结束执行。
如果在【session】没有找到共享数据,到【application】定位共享数据,如果定位成功读取输出并结束执行。
如果在【application】没有找到共享数据,此时返回null。
弊端
- 增加程序运行时间。
- 导致定位数据错误。
使用场景
简化版设计之初就是为了从当前页作用域对象读取数据并输出。所以从request,session,application读取数据并输出时应该避免使用简化版。
EL运算表达式
- EL表达式允许开发人员将读取共享数据进行相关运算之后,再进行输出。
- EL表达式支持运算:
- 数学运算表达式
- 关系运算表达式
- 逻辑运算表达式
- EL表达式提供了一个用于测试对象是否为空的特殊运算符”empty”,其语法形式为${empty 变量名},它能判断当前变量(确切的硕,应该是命名空间)是否为空。在以下情况下empty运算符返回true:
- 当前变量不存在(即没有定义)。
- 当前变量值为null
- 当前变量引用集合(Set、list、Map)类型的对象,并且在当前集合对象中不包含任何元素。
- 注意:empty运算符可以与”!”运算符一起使用。
EL表达式高级类型对象的属性输出
命令格式
${作用域对象别名.共享数据名.属性名}
命令作用
从作用域对象读取到指定的高级类型对象,并将高级类型对象中指定属性内容写入到响应体。
EL表达式专有异常
异常描述
javax.el.PropertyNotFoundException:类型【xxxx】不存在【属性名】既在某个类中没有找到对应的属性。
异常原因分析
- EL表达式在读取对象中属性时,通过【反射机制】调用当前属性对应的get方法得到属性的值,如果当前属性没有声明对应get方法,此时EL表达式认为当前
类文件没有这个属性。
隐式对象
概述
在EL表达式中可以直接使用的一组工具对象,用于提供对EL表达式功能扩充。
详解
名称 | 说明 |
---|---|
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) 获得)。 |
EL表达式禁用
在当前JSP文件中禁用EL表达式
<%@ page isELIgnored="true" %> <%--表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止--%>
在整个项目中禁用EL表达式
*.jsp
true
JSON工具包
JSON工具包创建(对象)
Servlet
// 1.得到一个部门类型的对象
Dept dept = new Dept(1,"张三","浙江省 金华市 金东区");
// 2.通过json工具包中的工具类将部门对象内容转换成JSON格式字符串
JSONObject jsonObject = JSONObject.fromObject(dept);
//3.将JS0N格式字符串添加请求作用域对象
request.setAttribute("key", jsonObject.toString());
//4.请求转发
request.getRequestDispatcher("/index_02.jsp").forward(request, response);
JSP
function init() {
var deptObj = ${requestScope.key};
document.getElementById("deptNo").value = deptObj.deptNo;
document.getElementById("deptName").value = deptObj.deptName;
document.getElementById("loc").value = deptObj.loc;
}
JSON工具包创建(集合)
Servlet
// 1.得到一个用户类型的对象
Dept dept01 = new Dept(1,"张三","浙江省 金华市 金东区");
Dept dept02 = new Dept(2,"李四","河南省 开封市 杞县");
Dept dept03 = new Dept(3,"王五","台湾 台东县 延平乡");
Dept dept04 = new Dept(4,"赵六","海南省 三沙市 南沙群岛");
// 2.将用户对象放置到集合中
List deptList = new ArrayList();
deptList.add(dept01);
deptList.add(dept02);
deptList.add(dept03);
deptList.add(dept04);
// 2.通过json工具包中的工具类将集合内容转换成JSON数组格式字符串
JSONArray jsonArray = JSONArray.fromObject(deptList);
//3.将JS0N数组格式字符串添加请求作用域对象
request.setAttribute("key", jsonArray.toString());
//4.请求转发
request.getRequestDispatcher("/index_03.jsp").forward(request, response);
JSP
function init() {
var jsonArray = ${requestScope.key};
var one = document.getElementById("one");
for (var i = 0; i < jsonArray.length; i++) {
var jsonobj = jsonArray[i];
var trDom = document.createElement("tr");
var tdDom01 = document.createElement("td");
var tdDom02 = document.createElement("td");
var tdDom03 = document.createElement("td");
tdDom01.innerHTML = jsonobj.deptNo;
tdDom02.innerHTML = jsonobj.deptName;
tdDom03.innerHTML = jsonobj.loc;
trDom.appendChild(tdDom01);
trDom.appendChild(tdDom02);
trDom.appendChild(tdDom03);
one.appendChild(trDom);
}
}