EL表达式
EL表达式概念
[!note]
EL(Expression Language,表达式语言)是一种用于在Java EE Web应用程序中访问和操作数据的简洁且功能强大的语言。它是JavaServer Pages(JSP)规范的一部分,最初引入于JSP 2.0规范中。
EL提供了一种在JSP页面中嵌入表达式的方式,以便在页面中访问JavaBean组件、请求参数、会话属性等数据。它使得在JSP页面中的数据操作更加简洁和灵活,从而降低了JSP页面的复杂度。
[!important]
EL表达式格式:${表达式}
EL表达式作用
[!note]
访问数据: EL允许在JSP页面中轻松地访问和展示数据。通过EL表达式,可以直接从请求、会话、应用程序范围内的属性中提取数据,也可以访问JavaBean组件中的属性。这样,可以在JSP页面中快速地展示数据库中的数据,或者显示用户提交的表单数据。
简化代码: EL简化了JSP页面中的代码编写。通过使用
${}
语法,可以直接在JSP页面中引用数据,而不需要编写Java代码来获取数据并将其放入页面上下文中。这样,可以减少JSP页面中的Java代码量,使页面更加简洁、易读和易维护。执行逻辑操作: EL支持执行逻辑操作,例如算术运算、关系运算和逻辑运算。通过EL表达式,可以在JSP页面中执行简单的逻辑操作,例如计算两个数的和或者判断两个字符串是否相等。
动态页面生成: EL可以使JSP页面动态生成内容。通过使用EL表达式,可以根据条件展示或隐藏特定的内容,也可以根据数据的值动态地生成页面元素,从而实现动态页面的构建和渲染。
国际化支持: EL支持国际化(i18n)功能。通过EL表达式,可以在JSP页面中轻松地引用资源文件中的文本,并根据用户的语言偏好动态地显示相应的文本内容,从而实现多语言支持。
EL表达式搜索四个域中的顺序
在四个域中有同key的数据
[!tip]
在Java EE Web 应用程序中,EL 表达式搜索四个域(scope)的顺序通常是以下顺序:
Page Scope(页面范围):
- 页面范围指的是当前 JSP 页面的生命周期内有效的对象。在 EL 表达式中,可以直接访问在当前 JSP 页面中声明的局部变量,这些变量只在当前页面中可见。
Request Scope(请求范围):
- 请求范围指的是当前 HTTP 请求的生命周期内有效的对象。在 EL 表达式中,可以访问请求对象(HttpServletRequest)的属性,这些属性在整个请求过程中都有效。
Session Scope(会话范围):
- 会话范围指的是用户会话的生命周期内有效的对象。在 EL 表达式中,可以访问会话对象(HttpSession)的属性,这些属性在用户会话期间都有效。
Application Scope(应用程序范围):
- 应用程序范围指的是整个 Web 应用程序的生命周期内有效的对象。在 EL 表达式中,可以访问应用程序对象(ServletContext)的属性,这些属性在整个应用程序中都有效。
EL 表达式在搜索这四个域时,会按照以上的顺序进行搜索。即,首先在页面范围搜索,然后是请求范围,接着是会话范围,最后是应用程序范围。如果在某一个域中找到了符合条件的变量或属性,EL 表达式就会停止搜索并返回找到的值。如果在所有域中都找不到符合条件的变量或属性,EL 表达式会返回 null。
EL表达式输出复杂的JavaBean对象
per是一个复杂对象
[!warning]
<div>${per}</div> <div>${per.name}</div> <div>${per.phones[0]}</div> <div>${per.cities.get(0)}</div> <div>${per.cities[0]}</div> <div>${per.map}</div> <div>${per.map.get("key1")}</div> <div>${per.map.key2}</div>
EL表达式运算
关系运算符
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
== 或者 eq | 等于 | ${a == b} 或者 ${a eq b} | true 如果 a 等于 b ,否则为 false |
!= 或者 ne | 不等于 | ${a != b} 或者 ${a ne b} | true 如果 a 不等于 b ,否则为 false |
< 或者 lt | 小于 | ${a < b} 或者 ${a lt b} | true 如果 a 小于 b ,否则为 false |
<= 或者 le | 小于或等于 | ${a <= b} 或者 ${a le b} | true 如果 a 小于或等于 b ,否则为 false |
> 或者 gt | 大于 | ${a > b} 或者 ${a gt b} | true 如果 a 大于 b ,否则为 false |
>= 或者 ge | 大于或等于 | ${a >= b} 或者 ${a ge b} | true 如果 a 大于或等于 b ,否则为 false |
逻辑运算符
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
&& 或者 and | 逻辑与 | ${a && b} 或者 ${a and b} | true 如果 a 和 b 都为 true ,否则为 false |
|| 或者 or | 逻辑或 | `${a | |
!或者not | 逻辑非 | ${!a} 或者 ${not a} | true 如果 a 为 false ,否则为 true |
算术运算符
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
+ | 加法 | ${a + b} | a 与 b 的和 |
- | 减法 | ${a - b} | a 与 b 的差 |
* | 乘法 | ${a * b} | a 与 b 的积 |
/ | 除法 | ${a / b} | a 与 b 的商 |
% | 取模 | ${a % b} | a 除以 b 的余数 |
empty运算
empty
是一个特殊的运算符,用于检查集合、数组、字符串或对象是否为空。
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
empty | 检查是否为空 | ${empty collection} 或者 ${empty string} 或者 ${empty object} | true 如果集合、数组、字符串或对象为空,否则为 false |
三元运算符
点运算和中括号运算
.点运算Bean对象的属性值
[]中括号运算有序集合中的元素
[]中括号运算map集合的key
EL表达式的11个隐含对象
变量 | 类型 | 作用 |
---|---|---|
pageScope | java.util.Map | 当前页面范围内的属性 |
requestScope | java.util.Map | HTTP 请求范围内的属性 |
sessionScope | javax.servlet.http.HttpSession | HTTP 会话范围内的属性 |
applicationScope | javax.servlet.ServletContext | 应用程序范围内的属性 |
param | java.util.Map | 请求参数的集合 |
paramValues | java.util.Map | 请求参数的值的数组 |
header | java.util.Map | HTTP 请求头的集合 |
headerValues | java.util.Map | HTTP 请求头的值的数组 |
cookie | java.util.Map | HTTP 请求中的 cookie 的集合 |
initParam | java.util.Map | 当前 Web 应用程序的初始化参数的集合 |
pageContext | javax.servlet.jsp.PageContext | 当前页面的上下文对象 |
获取四个特定域中的属性
域 | EL 表达式示例 |
---|---|
pageScope | ${pageScope.attributeName} |
requestScope | ${requestScope.attributeName} |
sessionScope | ${sessionScope.attributeName} |
applicationScope | `${applicationScope.attributeName} |
[!tip]
pageContext使用
- 协议
- 服务器ip
- 服务器端口
- 获取工程路径
- 获取请求方法
- 获取客户端ip
- 获取会话的id编号
信息 | 获取示例 |
---|---|
协议 | ${pageContext.request.scheme} 或者 ${pageContext.request.protocol} |
服务器 IP | ${pageContext.request.serverName} 或者 ${pageContext.request.getLocalName()} |
服务器端口 | ${pageContext.request.serverPort} 或者 ${pageContext.request.getLocalPort()} |
获取工程路径 | ${pageContext.request.contextPath} |
获取请求方法 | ${pageContext.request.method} |
获取客户端 IP | ${pageContext.request.remoteAddr} |
获取会话的 ID 编号 | ${pageContext.session.id} |
JSTL标签库
[!tip]
JSTL(JavaServer Pages Standard Tag Library)是一个用于简化 JSP 开发的标签库。它提供了一组标签,用于执行常见的任务,如迭代、条件判断、格式化数据等
5个组成
标签库 | 标签名 | 作用 |
---|---|---|
核心标签库(core) | <c:forEach> | 迭代集合或数组 |
<c:if> | 条件判断 | |
<c:choose> | 多重条件判断 | |
<c:when> | 多重条件判断的分支 | |
<c:otherwise> | 多重条件判断的默认分支 | |
<c:set> | 设置变量 | |
格式化标签库(fmt) | <fmt:formatDate> | 格式化日期 |
<fmt:formatNumber> | 格式化数字 | |
SQL 标签库(sql) | <sql:setDataSource> | 设置数据源 |
<sql:query> | 执行查询 | |
XML 标签库(xml) | <x:parse> | 解析 XML |
<x:out> | 输出 XML | |
函数标签库(fn) | <fn:toUpperCase> | 将字符串转换为大写 |
<fn:toLowerCase> | 将字符串转换为小写 |
1.导入包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
2.标签库引入
核心标签库(Core)
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
格式化标签库(Formatting)
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
XML 标签库(XML)
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>
函数标签库(Functions)
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
SQL 标签库(SQL)
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
核心标签库(core)使用
set标签
属性 | 描述 | 是否必需 | 默认值 |
---|---|---|---|
var | 要设置的变量的名称 | 是 | 无 |
value | 要设置的变量的值,可以是常量、表达式或其他变量 | 是 | 无 |
scope | 变量的作用范围,可选值为 “page”、“request”、“session” 或 “application” | 否 | “page” |
[!tip]
<c:set>
标签是 JSTL 核心标签库中的一个标签,用于设置变量的值。它可以用来创建新的变量或者修改已存在变量的值。以下是<c:set>
标签的基本语法:<c:set var="variableName" value="expression" [scope="page|request|session|application"] />
- 创建一个新的变量:
<c:set var="name" value="John" />
- 设置一个已存在变量的值:
<c:set var="age" value="30" />
- 在特定作用域中设置变量的值:
<c:set var="status" value="active" scope="session" />
- 使用 EL 表达式作为变量的值:
<c:set var="fullName" value="${firstName} ${lastName}" />
- 创建一个集合类型的变量:
<c:set var="numbers" value="${[1, 2, 3, 4, 5]}" />
if标签
属性 | 描述 | 是否必需 | 默认值 |
---|---|---|---|
test | 要执行的条件表达式,如果表达式的值为 true,则执行标签体内的内容 | 是 | 无 |
[!tip]
<c:if>
标签是 JSTL 核心标签库中的一个标签,用于在 JSP 页面中执行条件判断。它类似于 Java 中的if
语句,根据给定的条件决定是否执行标签体内的内容。以下是<c:if>
标签的基本语法:<c:if test="${condition}"> <!-- 标签体内容 --> </c:if>
其中,
test
属性用于指定条件表达式,如果条件表达式的值为 true,则执行标签体内的内容。下面是一些<c:if>
标签的示例用法:
- 基本的条件判断:
<c:if test="${user.age > 18}"> <p>成年人</p> </c:if>
- 使用逻辑运算符:
<c:if test="${user.gender == 'male' && user.age > 18}"> <p>成年男性</p> </c:if>
- 嵌套使用:
<c:if test="${user.age > 18}"> <p>成年人</p> <c:if test="${user.gender == 'male'}"> <p>成年男性</p> </c:if> </c:if>
- 使用 EL 表达式的结果作为条件:
<c:if test="${not empty products}"> <table> <!-- 根据产品列表生成表格 --> </table> </c:if>
choose、when、otherwise标签
标签里不要使用html注释,要使用jsp注释
属性 | 描述 | 是否必需 | 默认值 |
---|---|---|---|
test | 用于指定条件表达式,如果条件表达式返回 true ,则执行该标签内的内容。 | 是 | 无 |
var | 可选属性,用于指定一个变量来存储满足条件的 when 子标签的索引。 | 否 | 无 |
[!tip]
核心标签库中的
choose
,when
, 和otherwise
标签通常用于在条件满足时执行不同的操作。这些标签通常用于模板引擎或类似的系统中,以根据条件执行不同的逻辑。下面是一个简单的示例,演示了这些标签的用法:
<choose> <when test="${condition1}"> <!-- 在满足条件1时执行的操作 --> <!-- 比如:<p>条件1成立</p> --> </when> <when test="${condition2}"> <!-- 在满足条件2时执行的操作 --> <!-- 比如:<p>条件2成立</p> --> </when> <otherwise> <!-- 当以上条件均不满足时执行的操作 --> <!-- 比如:<p>条件1和条件2均不成立</p> --> </otherwise> </choose>
在上面的示例中,
${condition1}
和${condition2}
是代表条件的占位符。具体的条件可以是任何返回布尔值的表达式,根据条件的不同,将会执行不同的逻辑。如果没有任何一个条件得到满足,则会执行<otherwise>
标签中的操作。这种结构可以用于在模板中根据不同的情况动态地生成内容,这样代码会更加灵活和易于维护。
<c:choose> <c:when test="${requestScope.heitht >100}"> <h1>大于100</h1> </c:when> <c:when test="${requestScope.height > 50}"> <h1>大于50</h1> </c:when> <c:otherwise> <c:choose> <c:when test="${requestScope.height > 40}"> <h1>其他1</h1> </c:when> <c:when test="${requestScope.height >30}"> <h1>其他2</h1> </c:when> </c:choose> </c:otherwise> </c:choose>
forEach标签
属性 | 描述 | 是否必需 | 默认值 |
---|---|---|---|
items | 要迭代的集合,可以是数组、列表或者其他可迭代对象。 | 是 | 无 |
var | 迭代过程中的变量名,用于在每次迭代中存储当前元素的值。 | 是 | 无 |
varStatus | 可选属性,用于指定一个变量来存储关于迭代状态的信息,如当前索引、是否是第一个或最后一个元素等。 | 否 | 无 |
begin | 可选属性,指定迭代开始的索引。 | 否 | 0 |
end | 可选属性,指定迭代结束的索引(不包括)。 | 否 | 集合长度 |
step | 可选属性,指定每次迭代的步长,默认为1。 | 否 | 1 |
varStatus可以获取的值
值 | 描述 |
---|---|
index | 当前迭代的索引,从0开始计数。 |
count | 当前迭代的次数,从1开始计数。 |
first | 是否是第一次迭代,返回布尔值(true或false)。 |
last | 是否是最后一次迭代,返回布尔值(true或false)。 |
begin | 迭代范围的起始索引(默认为0)。 |
end | 迭代范围的结束索引(不包括)。 |
step | 迭代的步长(默认为1)。 |
[!tip]
遍历数组
假设我们有一个名为
array
的数组,其内容如下:String[] array = {"apple", "banana", "orange"};
我们可以使用 JSTL 的
forEach
标签来遍历该数组:<c:forEach items="${array}" var="item"> ${item} </c:forEach>
遍历列表
假设我们有一个名为
list
的列表,其内容如下:List<String> list = Arrays.asList("apple", "banana", "orange");
我们可以使用 JSTL 的
forEach
标签来遍历该列表:<c:forEach items="${list}" var="item"> ${item} </c:forEach>
遍历映射
假设我们有一个名为
map
的映射,其内容如下:Map<Integer, String> map = new HashMap<>(); map.put(1, "apple"); map.put(2, "banana"); map.put(3, "orange");
我们可以使用 JSTL 的
forEach
标签遍历该映射,并输出键值对:<c:forEach items="${map}" var="entry"> Key: ${entry.key}, Value: ${entry.value} </c:forEach>
在这些示例中,
${array}
,${list}
, 和${map}
分别代表数组、列表和映射,${item}
代表数组和列表中的每个元素,${entry}
代表映射中的每个键值对。