第 12 章 EL 表达式语言
12.1 基本语法
EL 表达式的基本形式为 ${var}。
如果在 JSP 文件的模本文本中使用 EL 表达式,那么表达式的值会输出到网页上。
如下 Java 表达式 和 EL 表达式的作用相同,都是用于输出请求参数 username:
java 表达式:<%=request.getParameter("username")%>
EL 表达式:${param.username}
EL 表达式 和 Java 表达式一样,即可以直接插入到 JSP 文件的模板文本中,也可以作为 JSP 标签的属性值。
<jsp:userBean id="myPageBean" scope="page" class="mypack.CounterBean"/>
<--!设置 myPageBean 的值-->
<jsp:setProperty name="myPageBean" property="name" value="${myPageBean.count + 1}"/>
12.1.1 访问对象的属性及数组的元素
EL 表达式可以使用符号 “.” 来访问对象的属性,如 ${customer.name},表示customer 对象的 name 属性。
也可以使用方括号运算符 “[]” 来访问对象的属性,如 ${customer[“name”]}。两者是等价的。
方括号运算符还可以用来访问数组中的元素,如 ${customer[0]},表示 customer数组中的第一个元素。
12.1.2 EL 运算符
运算符类型 | 运 算 符 | 说 明 | 范 例 | 结 果 |
---|---|---|---|---|
算术运算符 | + | 加 | ${16+5} | 21 |
- | 减 | ${16-5} | 11 | |
* | 乘 | ${16*5} | 80 | |
/ 或 div | 除 | ${16/5} | 3.2 | |
% 或 mod | 取模 | ${16%5} | 1 | |
关系运算符 | == 或 eq | 等于 | ${16==5} | false |
!= 或 ne | 不等于 | ${16!=5} | true | |
< 或 It | 小于 | ${16<5} | false | |
> 或 gt | 大于 | ${16>5} | true | |
<= 或 le | 小于等于 | ${16<=5} | false | |
>= 或ge | 大于等于 | ${16>=5} | true | |
逻辑运算符 | && 或 and | 逻辑与 | ${16>5 && 16<18} | true |
|| 或 or | 逻辑或 | ${16>5 || 16<18} | true | |
! 或 not | 逻辑非 | ${!(16>5)} | false | |
empty 运算符 | empty | 检查是否为空 | ${empty var} | var 为 null,返回true |
条件运算符 | a?b:c | 条件运算 | ${16>5 ? 16 : 5} | 16 |
对于“empty” 运算符,在以下情况返回true。
- var 变量不存在,即没有被定义。
- var 变量的值为 null。
- var
- var 变量引用的集合类型的对象,并且集合对象中不包含任何元素。
12.1.3 隐含对象
EL 语言定义了 11 个隐含对象,其中 10 个都是 Map 类型,可以通过这些隐含对象便捷的访问 Web 应用中的特定数据。
隐含对象的固定变量名 | 类 型 | 说 明 |
---|---|---|
applicationScope | java.util.Map | 把Web应用范围内的属性名和属性值都进行映射 |
cookie | java.util.Map | 把客户请求中的Cookie名和Cookie对象进行映射 |
header | java.util.Map | 把 HTTP 请求头部的项目名和项目值进行映射,如${heaser.host} 等价于<%=requeset.getHeader("host")%> |
headerValues | java.util.Map | 把 HTTP 请求头部的所有项目名和所有匹配的项目值的数目进行映射,如 ${headerValues["accept-language"] 等价于 <%=reqeust.getHeaders("accept-language")%>} |
initParam | java.util.Map | 把 Web 应用的初始化参数进行映射 |
pageContext | PageContext | 表示 javax.servelt.jsp.PageContext 对象 |
pageScope | java.util.Map | 把页面范围内的属性名和属性值进行映射 |
param | java.util.Map | 把客户请求中的参数名和参数值进行映射 |
paramValus | java.util.Map | 把客户请求中的参数名和所有匹配的参数值进行映射 |
requestScope | java.util.Map | 把请求范围内的属性名和属性值进行映射 |
sessionScope | java.util.Map | 把会话范围内的属性名和属性值进行映射 |
这11个隐含对象可以分为以下4中类型。
(1)表示 HTTP 请求中的特定数据,包括 header,headerValues,param,paramValues 和 cookie。
${header["user-agent"]}
等价于 :<%=request.getHeaders("user-agent")%>
${header.host}
等价于:<%=request.getHeader("host")%>
${cookie.username.value}
等价于:调用名为 username 的 cookie 对象的 getValue() 方法
${param.username}
等价于:<%=request.getParameter("username")%>
对于 ${header[“user-agent”]},由于 “user-agent” 含有特殊字符 “-”,此时必须采用“[]” 运算符来访问,采用 "."运算符时不合法的。
(2)表示特定范围,包括 pageScope、requestScope、sessionScope 和 applicationScope。
${sessionScope.cart.total}
等价于:调用会话范围内的属性名为 "cart" 的 ShoppingCart 对象的 getTotal() 方法。
${applicationScope.counter.count}
等价于:调用 Web 应用范围内的属性名为 “counter” 的 CounterBean 对象的 getCount() 方法。
(3)表示 PageContext 对象,对应 pageContext。
${pageContext.servletContext.serverInfo}
等价于:<%=application.getServerInfo()%>
${pageContext.reqeust.reqeustURL}
等价于:<%=request.getRequestURL()%>
(4)表示 Web 应用的初始化参数集合,对应 initParam。
${initParam.driver}
等价于:<%=application.getInitParameter("driver")%>
注意:在 EL 表达式中无法直接访问 JSP 文件中的隐含对象。
12.1.4 命名变量
EL 表达式中变量称为命名变量,它不是 JSP 文件中的局部变量或实例变量,而是存放在特定范围内的属性,命名变量的名字和特定范围内的属性名对应。例如:${username} 等价于一下代码:
<%
//从所有范围内寻找名为 “username” 的属性
String username = (String)pageContext.findAttribute("username");
if (username != null){
%>
<%=username%>
<%}%>
以下代码定义了一个 username 局部变量,再试图通过 ${username} 来访问这个变量:
<%
String username = "Tom"
%>
${username}
以上代码不会打印 username 局部变量。因为 ${username} 代表的是特定范围内的 username 属性,而不是 username 局部变量。如果所有范围内都不存在 username 属性,那么 ${username} 没有任何打印结果。
12.2 使用 EL 表达式的 JSP 范例
<html>
<head>
<title>expression language examples</title>
</head>
<body>
<h3>jsp expression language examples</h3>
<p>the following table illustrates some el expressions and implicit objects:
<table border="1">
<thead>
<td><b>expression</b></td>
<td><b>value</b></td>
</thead>
<tr>
<td>\${2 + 5}</td>
<td>${2 + 5}</td>
<tr>
<td>\${4/5}</td>
<td>${4/5}</td>
</tr>
<tr>
<td>\${5 div 6}</td>
<td>${5 div 6}</td>
</tr>
<tr>
<td>\${5 mod 7}</td>
<td>${5 mod 7}</td>
</tr>
<tr>
<td>\${2 < 3}</td>
<td>${2 < 3}</td>
</tr>
<tr>
<td>\${2 gt 3}</td>
<td>${2 gt 3}</td>
</tr>
<tr>
<td>\${3.1 le 3.2}</td>
<td>${3.1 le 3.2}</td>
</tr>
<tr>
<td>\${(5 > 3) ? 5 : 3}</td>
<td>${(5 > 3) ? 5 : 3}</td>
</tr>
<tr>
<td>\${header.host}</td>
<td>${header.host}</td>
</tr>
<tr>
<td>\${header["user-agent"]}</td>
<td>${header["user-agent"]}</td>
</tr>
</table>
</body>
</html>
在以上 jsp 文件中,“$” 为转义字符,代表真正的 “$” 字符,因此 “${header.host}” 将作为纯文本输出到网页上。
12.2.2 读取 HTML 表单数据的例子
param 隐含对象可用于读取 HTTP 请求参数,形式为 ${param[“var”]} 或 ${param.var}。 HTML 表单数据也属于请求参数。
<html><head><title>form content</title></head>
<body>
<h3>Fill-out-form</h3>
<p>
<form action="form.jsp" method="GET">
name=<input type="text" name="username" value="${param["username"]}">
<input type="submit" value="Submit">
</form>
<p>
The name is: ${param.username}
</body>
</html>
提交表单之前
提交表单后的结果
12.3 定义和使用 EL 函数
EL 表达式语言可以访问 EL 函数。EL 函数实际上与 Java 类中的方法对应。这个 Java 类必须定义为 public 类型,并且作为函数的方法也必须声明为 public static 类型。Java 类定义好后,需要在标签库描述符(TLD)文件中,把 Java 类的方法映射为函数。
public class Tool {
public static int add(String x, String y) {
int a = 0;
int b = 0;
try {
a = Integer.parseInt(x);
b = Integer.parseInt(y);
}catch(Exception e) {}
return a + b;
}
public static String convert(String str){
try{
return str.toUpperCase();
}catch(Exception e){return "";}
}
}
配置 TLD 文件
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.1</tlib-version>
<short-name>mytaglib</short-name>
<uri>/mytaglib</uri>
<function>
<description>add x and y</description>
<name>add</name>
<function-class>mypack.Tool </function-class>
<function-signature>
int add(java.lang.String,java.lang.String)
</function-signature>
</function>
<function>
<description>convert encoding</description>
<name>convert</name>
<function-class>mypack.Tool </function-class>
<function-signature>
java.lang.String convert(java.lang.String)
</function-signature>
</function>
</taglib>
在 web.xml 文件中加入<taglib>
元素
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0" >
<jsp-config>
<taglib>
<taglib-uri>/mytaglib</taglib-uri>
<taglib-location>/WEB-INF/mytaglib.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
使用自定义函数
<%@ page contentType="text/html; charset=GB2312" %>
<%@ taglib prefix="mm" uri="/mytaglib" %>
<html>
<head>
<title>functions</title>
</head>
<body>
<h3>Add Numbers</h3>
<p>
<form action="sum.jsp" method="get">
user= <input type="text" name="user"
value="${mm:convert(param.user)}">
<br>
<mm:hello/>
x = <input type="text" name="x" value="${param.x}">
<br>
y = <input type="text" name="y" value="${param.y}">
<input type="submit" value="Add Numbers">
</form>
<p>
the sum is: ${mm:add(param.x,param.y)}
</body>
</html>