【JavaWeb学习 | 第20篇】EL表达式与JSTL标签
在前面几篇文章中,我们已经学习了 JSP内置对象、Servlet + MVC模式、Filter过滤器。
但如果你仔细观察之前的JSP页面示例,会发现里面还残留着大量的 <% %> Java脚本和 <%= %> 表达式,这会导致页面非常混乱,前后端不分离的问题依然存在。
EL表达式 和 JSTL标签库 的出现,就是为了彻底减少甚至消除JSP中的Java脚本,让页面变得干净、优雅、专业。
一、EL表达式(Expression Language)
EL表达式 是 JSP 2.0 引入的一种简化表达式语言,用于从四大作用域中取出数据并输出。
1. 基本语法
${表达式}
2. EL表达式的四大作用域搜索顺序(非常重要!)
EL会按照以下顺序自动查找属性:
pageScope → requestScope → sessionScope → applicationScope
如果找到就立即返回,不再继续查找。
3. 常用EL表达式写法
<%-- 1. 输出作用域中的数据 --%>
${user} <%-- 直接输出对象,调用toString() --%>
${user.username} <%-- 调用user.getUsername() --%>
${user["username"]} <%-- 另一种写法,等价上面 --%>
<%-- 2. 四大作用域显式指定(推荐,避免歧义) --%>
${pageScope.msg}
${requestScope.errorMsg}
${sessionScope.user.username}
${applicationScope.onlineCount}
<%-- 3. 获取请求参数 --%>
${param.username} <%-- 相当于 request.getParameter("username") --%>
${paramValues.hobby[0]} <%-- 获取同名参数的第一个值 --%>
<%-- 4. 获取请求头、Cookie等 --%>
${header["User-Agent"]}
${cookie.JSESSIONID.value}
<%-- 5. 运算支持 --%>
${10 + 5} <%-- 15 --%>
${empty user} <%-- 判断是否为空(null或空字符串、空集合) --%>
${user == null ? "未登录" : "已登录"}
小技巧:
${pageContext.request.contextPath}→ 动态获取项目根路径(强烈推荐在form的action和超链接中使用)${pageContext.request.method}→ 获取请求方式
二、JSTL标签库(JavaServer Pages Standard Tag Library)
JSTL 是 Apache 提供的标准标签库,包含四大标签库。我们最常用的是 核心标签库(c标签) 和 格式化标签库(fmt标签)。
1. 引入JSTL标签库(必须先导入)
在JSP页面顶部添加:
<%-- 核心标签库(最常用) --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%-- 格式化标签库(日期、数字格式化) --%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
2. 核心标签库(c标签)常用标签
<%-- 1. <c:out>:输出内容(比${}更安全,可防XSS) --%>
<c:out value="${user.username}" default="未知用户" />
<%-- 2. <c:set>:向作用域存值 --%>
<c:set var="msg" value="Hello JSTL" scope="request" />
<%-- 3. <c:if>:单条件判断 --%>
<c:if test="${not empty user}">
<h2>欢迎 ${user.username} 回来!</h2>
</c:if>
<%-- 4. <c:choose> + <c:when> + <c:otherwise>:多条件判断(类似switch) --%>
<c:choose>
<c:when test="${score >= 90}">优秀</c:when>
<c:when test="${score >= 80}">良好</c:when>
<c:when test="${score >= 60}">及格</c:when>
<c:otherwise>不及格</c:otherwise>
</c:choose>
<%-- 5. <c:forEach>:循环遍历(最常用!) --%>
<table border="1">
<tr><th>编号</th><th>姓名</th><th>年龄</th></tr>
<c:forEach items="${userList}" var="u" varStatus="status">
<tr>
<td>${status.count}</td> <%-- 从1开始 --%>
<td>${u.username}</td>
<td>${u.age}</td>
</tr>
</c:forEach>
</table>
<%-- 6. <c:forTokens>:按分隔符分割字符串 --%>
<c:forTokens items="java,php,python" delims="," var="lang">
${lang}<br>
</c:forTokens>
<%-- 7. <c:redirect>:重定向 --%>
<c:redirect url="/login.jsp" />
3. 格式化标签(fmt)简单示例
<%-- 日期格式化 --%>
<fmt:formatDate value="${now}" pattern="yyyy年MM月dd日 HH:mm:ss" />
<%-- 数字格式化 --%>
<fmt:formatNumber value="12345.6789" pattern="#,##0.00" />
三、EL + JSTL 对比传统脚本(直观对比)
传统写法(不推荐):
<%
List<User> list = (List<User>) request.getAttribute("userList");
if(list != null) {
for(User u : list) {
%>
<tr><td><%= u.getUsername() %></td></tr>
<%
}
}
%>
现代推荐写法(干净优雅):
<c:forEach items="${userList}" var="u">
<tr><td>${u.username}</td></tr>
</c:forEach>
四、实际开发最佳实践
- JSP页面中尽量只使用 EL + JSTL + HTML,杜绝
<% Java代码 %>。 - 复杂逻辑放在 Servlet/Service 层,JSP 只负责展示。
- 所有超链接和表单action 都写成:
${pageContext.request.contextPath}/user/list
- 使用
<c:out>输出用户提交的内容,防止XSS攻击。 - 在项目中统一把 JSTL 的 jar 包放入
WEB-INF/lib(jstl-1.2.jar+taglibs-standard-impl-1.2.5.jar等)。
五、练习建议(强烈推荐动手)
- 把之前登录成功的
success.jsp改造成纯EL + JSTL版本。 - 在Servlet中查询一个用户列表(List),存入request作用域,用
<c:forEach>在JSP中表格展示。 - 实现一个商品列表页面,包含分页信息,用JSTL循环展示。
- 使用
<c:if>和<c:choose>实现不同用户角色显示不同菜单。
做完这几个练习,你会明显感觉到JSP页面变得“清爽”了很多!
系列文章导航(持续更新中):
- 第18篇:Servlet与MVC
- 第19篇:Filter过滤器
- 第20篇:EL表达式与JSTL标签(本文)
- 第21篇:Listener监听器(在线人数统计、Session创建与销毁监听等)
下一篇文章预告:我们将学习 Listener(监听器),它能监听应用、会话、请求的生命周期,是实现“在线人数统计”、“网站访问量统计”等功能的利器。
有任何疑问(比如 <c:forEach> 的 varStatus 详细用法、如何在Maven项目中引入JSTL等),欢迎在评论区留言,我会立刻补充示例代码!
继续加油!当你彻底掌握 EL + JSTL 后,JSP页面将不再是“脚本大杂烩”,而是变得结构清晰、专业美观,这也是从“JavaWeb初学者”迈向“能写规范项目”的重要一步!✨
下一篇文章见~ 🚀