一、前言
在传统的Java Web 开发中,为了处理页面逻辑和数据展示,传统的JSP页面常常变得复杂、难以维护,甚至会混淆业务逻辑与表示层。为了应对这些问题,JavaServer Pages Standard Tag Library(JSTL)应运而生,它提供了一套标准标签库,以简化JSP的开发,降低页面上的Java代码量,提高可读性,降低潜在的错误风险。
本文将探讨JSTL标签库的使用,包括核心标签库、条件判断、集合遍历、和格式化标签等方面。
二、内容
2.1 背景
当编写JavaServer Pages(JSP)页面时,经常需要嵌入Java代码以完成页面展示和业务逻辑。然而,这样的做法会导致页面代码变得复杂、难以维护,而且容易混淆业务逻辑与表示层。为了解决这个问题,JSP引入了JSTL(JavaServer Pages Standard Tag Library),这是一个标准的标签库,用于简化JSP的开发。
2.2 概述
JSTL(JavaServer Pages Standard Tag Library)是一个由SUN(现在是Oracle)定义的规范,由Apache Tomcat团队等实现的标签库。它旨在提供一种更简单、更结构化的方法来处理常见的页面逻辑和数据展示任务。JSTL不仅能提高JSP代码的可读性,还有助于减少页面上的Java代码量,从而降低了错误的潜在风险。
2.3 准备工作
(1)下载
官方地址:tomcat.apache.org
首先打开官网:
然后往下找,找到 Apache Standard Taglib 1.2.5 Released
点击 Download后,在新页面的下方,下载 Impl 和 Spec 即可:
备注:
JSTL1.2.5是JSTL的一个特定版本,其中包含一组JSTL标签库的相关组件。
其中:
- taglibs-standard-impl-1.2.5.jar(标签库实现包,必须):
- 作用:该组件实现了JSTL标签库的功能。它包含了JSTL标签的实际执行代码,以便在JSP页面上执行相应的操作。
- 描述:该组件是JSTL标准规范的实现部分,必须包含在项目中,以确保JSTL标签的功能正常工作。
- taglibs-standard-spec-1.2.5.jar(标签库定义包,必须):
- 作用:这是JSTL标准规范的一部分,包含了JSTL标签库的定义。它定义了JSTL标签的语法和功能,以便开发人员可以在JSP页面中使用这些标签。
- 描述:该组件是JSTL标准规范的核心部分,必须包含在项目中,以确保JSTL标签的正常使用。
- taglibs-standard-jstlel-1.2.5.jar(EL表达式支持包,备选):
- 作用:此组件提供对EL(Expression Language)表达式的支持,允许您在JSTL标签中使用EL表达式来引用和处理数据。
- 描述:它是可选的,EL已经内置了,不需额外引入。
- taglibs-standard-compat-1.2.5.jar(1.0版本兼容包,备选):
- 作用:此组件提供了对JSTL 1.0版本的兼容性支持。如果您的项目使用较旧的JSTL 1.0版本,可以包括此组件,以确保平滑迁移和兼容性。
- 描述:这是一个可选的组件,仅在需要与JSTL 1.0版本的代码进行互操作时才需要包括。
(2)安装
安装JSTL标签库是为了使我们的Java Web应用程序能够使用JSTL标签。有两种常见的安装方式。
第一种方法是将Jar文件复制到工程的 /WEB-INF/lib 目录(推荐)。
也就是说将之前下载好的taglibs-standard-spec-1.2.5.jar(标签库定义包)和taglibs-standard-impl-1.2.5.jar(标签库实现包)复制到我们的Web应用程序的/WEB-INF/lib目录中。
此时应用的目录结构应该是这样的:
/WEB-INF/lib/taglibs-standard-spec-1.2.5.jar/WEB-INF/lib/taglibs-standard-impl-1.2.5.jar。
重新部署Web应用程序,以使JSTL库生效。
之后在JSP页面中,我们可以通过<%@taglib>指令引入JSTL标签库,以便使用JSTL标签。
方式二是将Jar文件复制到Tomcat安装目录的lib目录。
这样的方式,最大的区别是这两个jar包对所有部署在Tomcat中的Web应用程序可用。
但一般推荐使用第一种方法,因为它更灵活,允许应用自行管理其依赖关系。
2.4 JSTL 标签库
(1)五种标签库
JSTL包含几个不同的标签库,每个标签库都专注于不同的任务,使开发人员能够更轻松地完成特定的操作。以下是主要的JSTL标签库:
- 核心标签库(Core Library)(前缀:c):
- 这个标签库提供了一组基本的标签,用于控制流程、条件判断、迭代循环以及其他基本操作。
- 核心标签库是JSTL中最常用的标签库,用于处理通用任务。这些标签使得我们可以在JSP页面中执行通用的控制逻辑,而无需编写大量的Java代码。
- 格式化标签库(Formatting Library)(前缀:fmt):
- 格式化标签库包含了一组标签,用于格式化日期、数字、货币等数据,同时支持国际化和本地化操作。
- 这对于显示和处理多语言和多地区的数据非常有用。
- SQL标签库(SQL Library)(前缀:sql)
- SQL标签库允许我们在JSP页面中执行SQL查询和数据库操作。
- 尽管实际应用中,不推荐在JSP中执行数据库操作。
- XML标签库(XML Library)(前缀:x)
- XML标签库包含了一组标签,用于处理XML文档,包括XML解析、遍历、转换以及其他与XML相关的操作。
- 这对于与XML数据交互的Web应用程序非常有用。
- 函数标签库(Functions Library):
- 函数标签库提供了一组自定义EL(Expression Language)函数,用于执行字符串处理和其他常见操作。
- 这些函数可用于在JSP页面上执行各种处理任务。
后三种标签库很少使用
(2)引用核心标签库 core
要引用JSTL核心标签库,我们使用JSP页面上的 <%@ taglib> 指令。这个指令告诉JSP引擎要引用哪个标签库以便在页面中使用其中的标签。
引用 JSTL核心标签库的示例如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
在这个指令中,有两个主要属性:
- prefix(前缀):这是一个用户定义的短名称,用于标识标签库中的标签。在示例中,我们将
c作为JSTL核心标签库的前缀,这个前缀将在页面中引用标签时使用(约定俗成)。 - uri(统一资源标识符):这个属性定义了标签库的统一资源标识符,通常是一个URL或URI。它用于唯一标识标签库。在示例中,
uri="http://java.sun.com/jsp/jstl/core"是JSTL核心标签库的URI。
JSTL核心标签库的定义通常存储在JSTL的JAR文件中,即 taglibs-standard-impl-1.2.5.jar。
具体来说,这些定义信息存储在META-INF/c.tld文件中,这个TLD(Tag Library Descriptor)文件包含了核心标签库中各个标签的描述和配置信息。
如下所示:
引入核心标签库的 <%@ taglib> 指令允许JSP引擎识别并解析这些标签,从而可以在JSP页面中使用它们。
(3)常用标签
以下是 JSTL 标签的功能和用法:
| 标签名 | 描述 | 用法示例 |
|---|---|---|
<c:out> | 将表达式的结果输出到页面中 | <c:out value="${expression}" /> |
<c:set> | 在指定范围内设置变量或属性值 | <c:set var="varName" value="${expression}" /> |
<c:if> | 类似于Java if语句,用于条件判断 | <c:if test="${condition}">...</c:if> |
<c:choose> | 类似于Java switch关键字,为<c:when>和<c:otherwise>的父标签 | <c:choose> ... </c:choose> |
<c:when> | <c:choose>的子标签,用来判断条件是否成立 | <c:when test="${condition}">...</c:when> |
<c:otherwise> | <c:choose>的子标签,当所有的<c:when>标签判断为false时被执行 | <c:otherwise>...</c:otherwise> |
<c:forEach> | 类似于Java for,用于迭代集合中的信息 | <c:forEach items="${collection}" var="item">...</c:forEach> |
<c:forTokens> | 类似于Java split,用于分隔字符串 | <c:forTokens items="${tokenString}" delims="," var="token">...</c:forTokens> |
<c:remove> | 用于删除数据 | <c:remove var="varName" scope="page" /> |
<c:catch> | 用于捕获异常 | <c:catch var="ex">${expression}</c:catch> |
<c:import> | 用来导入静态或动态文件 | <c:import url="path/to/resource" /> |
<c:param> | 用来传入参数 | <c:param name="paramName" value="${paramValue}" /> |
<c:redirect> | 用于将当前页面重定向至另一个URL | <c:redirect url="newPage.jsp" /> |
<c:url> | 用于将URL格式化为一个字符串 | <c:url value="path/to/resource.jsp" var="urlString" /> |
2.5 条件判断
(1)c:if
首先我们来看一下单分支判断标签 <c:if>。
该标签的使用方式很简单。先看一个例子。
比如现在有一个 Servlet 类,用于处理HTTP GET请求。在doGet方法中,我们设置了一个名为score的属性,分数设置为47。然后将请求转发到名为core.jsp的JSP页面:
在 core.jsp 方法,我们引用了JSTL核心标签库,在页面中,我们使用了<c:if>标签进行条件判断。
效果如下:
下面, 我们来记录 <c:if> 标签语法。
<c:if test="判断条件" [var="varname"] [scope="request|page|session|application"] >
代码块
</c:if>
其中:
test:- 用于指定
if判断的条件,通常是一个表达式或布尔条件,返回值为boolean。 - 如果条件为真(
true),则<c:if>内部的代码块将被执行。如果条件为假(false),则内部代码块将被跳过。
- 用于指定
var:- 用于存储条件的执行结果,通常是一个
boolean值,该属性是可选的。 - 如果指定了
var属性,条件的结果将被存储在命名的变量中,以供稍后在JSP页面中使用。
- 用于存储条件的执行结果,通常是一个
scope:- 用于指定条件结果的作用域,该属性是可选的。
- 如果未指定,条件结果将默认存储在
page作用域中。我们可以指定作用域为request、page、session或application,具体取决于希望在哪个范围内存储条件的结果。
(2)c:choose | c:when | c:otherwise
有时,我们会需要多分支判断标签。<c:choose>、<c:when> 和 <c:otherwise> 标签的工作方式类似于Java中的 switch-case 和 default 语句。它们允许我们根据条件的不同结果执行不同的操作,实现多分支条件判断。
我们来看一下这些标签是怎么使用的。
**<c:choose>**标签类似于Java中的 switch 关键字。它包含了多个<c:when>块和一个<c:otherwise>块,用于定义多分支的条件判断。<c:choose>标签会依次检查每个<c:when>块的条件,如果有条件为真,将执行匹配的<c:when>块内的内容;如果所有的<c:when>条件都为假,将执行<c:otherwise>块内的内容。
语法格式如下:
<c:choose>
<c:when test="expression1">
<!-- 当 expression1 为 true 时执行的代码块 -->
</c:when>
<c:when test="expression2">
<!-- 当 expression2 为 true 时执行的代码块 -->
</c:when>
<c:otherwise>
<!-- 当所有表达式都为 false 时执行的代码块 -->
</c:otherwise>
</c:choose>
OK,现在我们来看一个示例代码:
还是刚刚那个例子,我们修改一下 core.jsp的代码:
此时打开页面,效果如下:
2.6 遍历集合
(1)c:forEach
我们使用 JSTL 中的 <c:forEach> 标签来迭代一个集合中的对象(类似于 Java 中的 for 循环语句)。
以下是<c:forEach>标签的基本语法:
<c:forEach var="item" items="${collection}" [varStatus="status"] [begin="start"] [end="end"] [step="step"]>
<!-- Java程序或HTML代码 -->
</c:forEach>
下面是对这些属性的详细说明:
- var(必需):这个属性用于指定一个在迭代中代表集合中的元素的变量名。在每次迭代中,该变量会被赋值为集合中的一个元素,我们可以使用这个变量来访问元素的值。
- items(必需):这是一个表达式,用于指定要迭代的集合或数据结构。这可以是任何数据结构,如数组、Java集合、Map等。
<c:forEach>标签将遍历这个数据结构中的每个元素。 - varStatus(可选):此属性用于指定一个变量名,它将包含与迭代状态相关的信息,如当前迭代的索引、计数等。这个变量可用于访问迭代过程的信息。
- begin(可选):指定从数据集合中的哪个位置开始迭代。默认情况下,起始下标是0。
- end(可选):指定迭代结束的元素。我们可以使用这个属性来限制迭代的范围。
- step(可选):指定迭代的步长。默认情况下,步长是1,这意味着每次迭代都处理下一个元素。我们可以更改步长以跳过特定数量的元素。
在<c:forEach>标签内部,我们可以放置Java程序代码或HTML代码,以处理每个迭代中的元素。
(2)代码示例
下面举一个例子,比如现在有一个Javabean:
然后,我们在 Servlet 中进行如下设置:
下面,我们在 jsp 页面中遍历 companys 这个集合。
打开页面后效果如下:
备注:
<c:forEach items = "${requestScope.companys }" var = "c"> ... </c:forEach>上述标签改为 Java 代码如下:
List companys = (List)request.getAttribute("companys") for(Company c : companys){ ... }
2.7 格式化标签
JSTL 格式化(fmt)标签可以通过很简单的方式转换数字、日期。这些标签允许我们处理字符编码、日期、时间、数字、货币和资源包等方面的操作。
导入格式化标签库的语法如下:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
以下是JSTL格式化标签的功能和用法:
| 标签 | 说明 | 用法示例 |
|---|---|---|
<fmt:requestEncoding> | 设置请求数据的字符编码 | <fmt:requestEncoding value="UTF-8" /> |
<fmt:setLocale> | 用于设置用户本地化环境 | <fmt:setLocale value="en_US" /> |
<fmt:bundle> | 绑定资源 | <fmt:bundle basename="messages" var="msgBundle" /> |
<fmt:message> | 用来从指定的资源文件中调用信息 | <fmt:message key="greeting" bundle="${msgBundle}" /> |
<fmt:setBundle> | 绑定资源 | <fmt:setBundle basename="messages" var="msgBundle" /> |
<fmt:formatNumber> | 用于格式化数字、百分比和货币 | <fmt:formatNumber value="${number}" type="number" /> |
<fmt:parseNumber> | 用于解析数字、货币和百分比 | <fmt:parseNumber value="${formattedNumber}" type="number" /> |
<fmt:formatDate> | 用于使用不同的方式格式化日期 | <fmt:formatDate value="${date}" pattern="yyyy-MM-dd" /> |
<fmt:parseDate> | 用于把字符串类型的日期转换成日期数据类型 | <fmt:parseDate value="${dateString}" pattern="yyyy-MM-dd" /> |
<fmt:timeZone> | 用于指定时区 | <fmt:timeZone value="America/New_York" /> |
<fmt:setTimeZone> | 用于设定默认时区 | <fmt:setTimeZone value="America/New_York" /> |
三、总结
通过本文,我们了解了JSTL的背景和概述,以及如何准备和安装JSTL标签库。我们还探讨了JSTL的不同标签库,包括核心标签库、条件判断标签、集合遍历标签以及格式化标签,提供了示例代码来演示它们的用法。
通过学习JSTL,我们可以减少在JSP页面中的Java代码量,使代码更清晰、可维护。