JSP 标准标签库(JSTL)(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在 Java Web 开发中,JSP(JavaServer Pages)作为动态网页生成的核心技术,常需要处理复杂的逻辑与数据展示。然而,直接在 JSP 页面中编写大量的 Java 脚本代码,不仅容易导致代码混乱,还会降低可维护性。此时,JSP 标准标签库(JSTL) 就如同一把钥匙,帮助开发者以更简洁、规范的方式完成页面逻辑处理。本文将从基础到进阶,结合实例讲解 JSTL 的核心功能,帮助开发者高效利用这一工具提升开发效率。


一、JSTL 的核心价值:为什么需要它?

1.1 痛点与需求

在传统 JSP 开发中,开发者常面临以下问题:

  • 代码可读性差:页面中混杂大量 <% %> 脚本片段,难以区分业务逻辑与视图代码。
  • 重复劳动:遍历集合、条件判断等基础操作需要重复编写相似代码。
  • 维护成本高:复杂的逻辑分散在多个页面中,修改时容易出错。

JSTL 的出现,正是为了解决这些问题。它提供了一套预定义的标签(Tag),将常见的 Web 开发功能封装为可复用的组件。通过使用这些标签,开发者可以像搭积木一样构建页面逻辑,同时保持代码的清晰与规范。

1.2 JSTL 的核心设计理念

JSTL 基于以下原则设计:

  1. 标签即功能:每个标签对应一个特定功能(如循环、条件判断),减少代码冗余。
  2. 与 EL 表达式结合:与 JSP 内置的**表达式语言(EL)**深度集成,实现数据的高效引用与操作。
  3. 模块化设计:标签库分为多个子库(如核心标签库、格式化标签库),按需引入,避免功能臃肿。

二、JSTL 的基础使用:快速上手

2.1 环境准备与配置

在使用 JSTL 前,需确保项目中引入相关依赖。对于 Maven 项目,可在 pom.xml 中添加以下依赖:

<dependency>  
    <groupId>javax.servlet</groupId>  
    <artifactId>jstl</artifactId>  
    <version>1.2</version>  
</dependency>  

在 JSP 页面中,通过 <%@ taglib %> 指令引入核心标签库:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  

其中 prefix="c" 是自定义的标签前缀,后续标签均以 <c:标签名> 形式调用。

2.2 第一个 JSTL 示例:输出变量

假设我们希望在页面上显示一个动态字符串,传统方式需要编写:

<%  
    String message = "欢迎使用 JSTL!";  
%>  
<p><%= message %></p>  

而使用 JSTL 结合 EL 表达式,代码简化为:

<c:set var="message" value="欢迎使用 JSTL!" scope="page"/>  
<p><c:out value="${message}"/></p>  
  • <c:set> 标签将变量 message 存入页面作用域。
  • <c:out> 标签安全地输出 EL 表达式 ${message} 的值。

三、核心标签库详解:功能与案例

3.1 条件判断标签

3.1.1 <c:if>:简单的条件判断

当需要根据条件显示不同内容时,可使用 <c:if>

<c:if test="${user.isAdmin}">  
    <p>管理员权限可见内容</p>  
</c:if>  

比喻<c:if> 就像一道门,只有满足条件(钥匙)才能打开,展示门后的内容。

3.1.2 <c:choose>:多分支选择

若需处理多条件分支,使用 <c:choose> 结合 <c:when><c:otherwise>

<c:choose>  
    <c:when test="${score >= 90}">  
        <p>优秀</p>  
    </c:when>  
    <c:when test="${score >= 60}">  
        <p>及格</p>  
    </c:when>  
    <c:otherwise>  
        <p>不及格</p>  
    </c:otherwise>  
</c:choose>  

3.2 循环标签 <c:forEach>

3.2.1 遍历集合

假设有一个用户列表 users,可通过以下代码遍历并展示:

<c:forEach items="${users}" var="user" varStatus="status">  
    <tr>  
        <td>${status.count}</td>  
        <td>${user.name}</td>  
        <td>${user.email}</td>  
    </tr>  
</c:forEach>  
  • items 指定要遍历的集合(如 List 或数组)。
  • var 定义当前元素的变量名。
  • varStatus 提供循环状态信息(如索引、是否为奇数行等)。

3.2.2 固定次数循环

若需循环固定次数,可指定 beginendstep

<c:forEach begin="1" end="5" step="1" var="i">  
    <div>当前循环次数:${i}</div>  
</c:forEach>  

3.3 数据操作标签

3.3.1 <c:set>:变量赋值

除了基础赋值,<c:set> 还支持将数据存入不同作用域:

<c:set var="total" value="${price * quantity}" scope="session"/>  

3.3.2 <c:remove>:移除变量

当需要清理作用域中的变量时:

<c:remove var="message" scope="request"/>  

3.33 <c:import>:页面包含与导入

类似 <jsp:include>,但支持跨项目引入资源:

<c:import url="/common/header.jsp" charEncoding="UTF-8"/>  

四、进阶功能:格式化与 URL 操作

4.1 格式化标签库(<fmt>

4.1.1 日期格式化

使用 <fmt:formatDate> 标签格式化日期:

<fmt:formatDate value="${user.birthdate}" pattern="yyyy年MM月dd日"/>  

4.1.2 货币与数字格式化

<fmt:formatNumber value="${price}" type="currency" currencySymbol="¥"/>  

4.2 URL 标签库(<c:url>

4.2.1 构建带参数的 URL

<c:url value="/search" var="searchUrl">  
    <c:param name="keyword" value="${keyword}"/>  
    <c:param name="page" value="1"/>  
</c:url>  
<a href="${searchUrl}">搜索</a>  

五、实战案例:用户登录表单验证

5.1 需求分析

实现一个简单的登录页面,要求:

  1. 显示错误提示(如用户名或密码为空)。
  2. 成功登录后跳转至欢迎页面。

5.2 实现步骤

5.2.1 登录页面(login.jsp)

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
...  
<c:if test="${not empty error}">  
    <div class="alert">${error}</div>  
</c:if>  

<form action="login" method="post">  
    <input type="text" name="username" placeholder="用户名"  
        <c:if test="${empty username}">  
            required  
        </c:if>  
    >  
    <input type="password" name="password" placeholder="密码" required>  
    <button type="submit">登录</button>  
</form>  

5.2.2 登录处理(Servlet)

protected void doPost(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    String username = request.getParameter("username");  
    String password = request.getParameter("password");  
    if (username == null || username.isEmpty() || password == null || password.isEmpty()) {  
        request.setAttribute("error", "用户名或密码不能为空");  
        request.getRequestDispatcher("/login.jsp").forward(request, response);  
    } else {  
        // 模拟登录成功  
        request.getSession().setAttribute("user", new User(username));  
        response.sendRedirect("welcome.jsp");  
    }  
}  

5.2.3 欢迎页面(welcome.jsp)

<c:if test="${empty user}">  
    <c:redirect url="/login.jsp"/>  
</c:if>  

<h1>欢迎,${user.username}!</h1>  

六、JSTL 的最佳实践与注意事项

6.1 作用域管理

  • 避免滥用 Page 作用域:仅在当前页面内需临时存储数据时使用。
  • 谨慎使用 Session 作用域:过多的 Session 数据可能增加服务器负担。

6.2 性能优化

  • 减少嵌套标签层级:深层嵌套可能影响渲染效率,建议通过后端预处理逻辑简化。
  • 避免在循环内执行耗时操作:如数据库查询,应提前在 Servlet 中完成。

6.3 与框架的兼容性

  • Spring MVC 集成:可结合 Spring 的标签库(如 <spring:message>)实现国际化。
  • 避免标签库冲突:若使用其他标签库(如 Struts),需注意 prefix 前缀的唯一性。

结论

JSP 标准标签库(JSTL) 是 Java Web 开发中不可或缺的工具,它通过标签化的方式将复杂逻辑封装为简单组件,显著提升了代码的可维护性和开发效率。无论是条件判断、循环遍历,还是数据格式化,JSTL 都能以直观的语法提供解决方案。对于初学者,建议从核心标签(如 <c:if><c:forEach>)入手,逐步掌握其与 EL 表达式的结合技巧;中级开发者则可探索其与框架(如 Spring)的深度集成,进一步优化项目架构。

通过本文的讲解,希望读者能对 JSTL 有全面的认识,并在实际项目中灵活应用这些技术,让 Web 开发更加高效、规范。

最新发布