1. 概述
JavaServer Pages 标签库 (JSTL) 是一套用于实现常见操作的标签集,包括循环、条件格式化等功能。本文将详细介绍如何配置 JSTL 及使用其各类标签。
2. 环境配置
要启用 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" %>
接下来我们将介绍 JSTL 的五大类标签。
3. 核心标签
JSTL 核心标签库包含执行基础操作的标签,如输出值、变量声明、异常处理、循环和条件判断等。
3.1. <c:out>
标签
***<c:out>
用于显示变量中的值或隐式表达式的结果。**
它有三个属性:value
、default
和 escapeXML
。escapeXML
属性控制是否对 value
中的 XML 标签进行转义。
示例用法:
<c:out value="${pageTitle}"/>
3.2. <c:set>
标签
<c:set>
用于在 JSP 中声明作用域变量。可通过 var
和 value
属性分别指定变量名和值。
示例:
<c:set value="JSTL Core Tags Example" var="pageTitle"/>
3.3. <c:remove>
标签
<c:remove>
用于移除作用域变量(相当于将变量设为 null)。它接受 var
和 scope
属性,scope
默认为所有作用域。
示例:
<c:remove var="pageTitle"/>
3.4. <c:catch>
标签
<c:catch>
捕获其标签体内抛出的异常。异常对象会存储在 var
属性指定的变量中。
典型用法:
<c:catch var ="exceptionThrown">
<% int x = Integer.valueOf("a");%>
</c:catch>
检查异常是否发生:
<c:if test = "${exceptionThrown != null}">
<p>异常信息:${exceptionThrown} <br />
异常详情:${exceptionThrown.message}
</p>
</c:if>
3.5. <c:if>
标签
<c:if>
是条件标签,仅当 test
属性表达式为 true 时才执行其内容。评估结果可存储在 var
属性中。
3.6. <c:choose>
、<c:when>
和 <c:otherwise>
标签
<c:choose>
是实现 switch 或 if-else 逻辑的父标签,包含两个子标签:
<c:when>
:相当于 if/else-if<c:otherwise>
:相当于 else
<c:when>
通过 test
属性指定判断条件。示例:
<c:set value="<%= Calendar.getInstance().get(Calendar.SECOND)%>" var="seconds"/>
<c:choose>
<c:when test="${seconds le 30 }">
<c:out value="${seconds} 小于 30"/>
</c:when>
<c:when test="${seconds eq 30 }">
<c:out value="${seconds} 等于 30"/>
</c:when>
<c:otherwise>
<c:out value="${seconds} 大于 30"/>
</c:otherwise>
</c:choose>
3.7. <c:import>
标签
<c:import>
用于获取并展示绝对或相对 URL 的内容。
通过 url
和 var
属性分别指定 URL 和存储内容的变量。示例:
<c:import var = "data" url = "http://www.example.com"/>
3.8. <c:forEach>
标签
<c:forEach>
类似 Java 的 for/while/do-while 循环。items
属性指定要迭代的集合,begin
和 end
指定起始和结束索引(从 0 开始)。
step
属性控制每次迭代的索引增量。示例:
<c:forEach var = "i" items="1,4,5,6,7,8,9">
项目 <c:out value = "No. ${i}"/><p>
</c:forEach>
3.9. <c:forTokens>
标签
<c:forTokens>
用于分割字符串并迭代各部分。
类似 <c:forEach>
,但增加了 delim
属性指定分隔符。示例:
<c:forTokens
items = "Patrick:Wilson:Ibrahima:Chris"
delims = ":" var = "name">
<c:out value = "姓名: ${name}"/><p>
</c:forTokens>
3.10. <c:url>
和 <c:param>
标签
<c:url>
用于格式化 URL 并进行正确的请求编码。格式化后的 URL 存储在 var
属性中。
<c:param>
是其子标签,用于添加 URL 参数。示例:
<c:url value = "/core_tags" var = "myURL">
<c:param name = "parameter_1" value = "1234"/>
<c:param name = "parameter_2" value = "abcd"/>
</c:url>
3.11. <c:redirect>
标签
<c:redirect>
执行 URL 重写并重定向用户到指定页面。典型用法:
<c:redirect url="/core_tags"/>
4. 格式化标签
JSTL 格式化标签库提供便捷方式格式化文本、数字、日期、时间等变量,优化显示效果。
这些标签还能增强网站国际化能力。使用前需添加 taglib:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
4.1. <fmt:formatDate>
标签
<fmt:formatDate>
用于格式化日期或时间。value
属性指定日期,type
属性可选 date
、time
或 both
。
pattern
属性可自定义格式模式。示例:
<c:set var="now" value="<%= new java.util.Date()%>"/>
<fmt:formatDate type="time" value="${now}"/>
4.2. <fmt:parseDate>
标签
<fmt:parseDate>
与 <fmt:formatDate>
类似,但可指定日期解析器期望的格式模式。
解析日期示例:
<c:set var="today" value="28-03-2018"/>
<fmt:parseDate value="${today}" var="parsedDate" pattern="dd-MM-yyyy"/>
4.3. <fmt:formatNumber>
标签
<fmt:formatNumber>
按指定模式或精度渲染数字,type
属性可选 number
、currency
或 percentage
。示例:
<c:set var="fee" value="35050.1067"/>
<fmt:formatNumber value="${fee}" type="currency"/>
4.4. <fmt:parseNumber>
标签
<fmt:parseNumber>
与 <fmt:formatNumber>
类似,但可指定数字解析器期望的格式模式。
用法示例:
<fmt:parseNumber var="i" type="number" value="${fee}"/>
4.5. <fmt:bundle>
标签
<fmt:bundle>
是 <fmt:message>
的父标签,通过 basename
属性指定资源包,使其对子标签可用。
支持国际化,可指定区域相关对象。典型用法:
<fmt:bundle basename="com.baeldung.jstl.bundles.CustomMessage" prefix="verb.">
<fmt:message key="go"/><br/>
<fmt:message key="come"/><br/>
<fmt:message key="sit"/><br/>
<fmt:message key="stand"/><br/>
</fmt:bundle>
4.6. <fmt:setBundle>
标签
<fmt:setBundle>
在 JSP 中加载资源包并使其在整个页面可用。加载的资源包存储在 var
属性中。示例:
<fmt:setBundle basename="com.baeldung.jstl.bundles.CustomMessage" var="lang"/>
4.7. <fmt:setLocale>
标签
<fmt:setLocale>
为声明后的 JSP 部分设置区域。典型用法:
<fmt:setLocale value="fr_FR"/>
fr_FR
表示法语区域。
4.8. <fmt:timeZone>
标签
<fmt:timeZone>
是父标签,指定其内部标签的时间格式化/解析操作使用的时区。
时区通过 value
属性指定。示例:
<fmt:timeZone value="${zone}">
<fmt:formatDate value="${now}" timeZone="${zn}"
type="both"/>
</fmt:timeZone>
4.9. <fmt:setTimeZone>
标签
<fmt:setTimeZone>
将 value
属性指定的时区复制到 var
属性指定的作用域变量。示例:
<fmt:setTimeZone value="GMT+9"/>
4.10. <fmt:message>
标签
<fmt:message>
用于显示国际化消息。需通过 key
属性指定消息的唯一标识符。
可通过 bundle
属性指定特定的资源包。示例:
<fmt:setBundle basename = "com.baeldung.jstl.bundles.CustomMessage" var = "lang"/>
<fmt:message key="verb.go" bundle="${lang}"/>
4.11. <fmt:requestEncoding>
标签
<fmt:requestEncoding>
为 post
类型的表单指定编码类型。
编码名称通过 value
属性指定。示例:
<fmt:requestEncoding value = "UTF-8" />
5. XML 标签
JSTL XML 标签库提供在 JSP 中操作 XML 数据的便捷方式。使用前需添加:
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
5.1. <x:out>
标签
<x:out>
类似 JSP 的 <%= %>
脚本标签,但专用于 XPath 表达式。
select
和 escapeXML
属性分别指定 XPath 表达式和是否转义特殊 XML 字符。简单示例:
<x:out select="$output/items/item[1]/name"/>
$output
指预加载的 XSL 文件。
5.2. <x:parse>
标签
<x:parse>
解析 xml
或 doc
属性指定的 XML 数据。典型示例:
<x:parse xml="${xmltext}" var="output"/>
5.3. <x:set>
标签
<x:set>
将 select
属性的 XPath 表达式结果存储到 var
属性指定的变量中。示例:
<x:set var="fragment" select="$output//item"/>
5.4. <x:if>
标签
<x:if>
当 select
属性的 XPath 表达式为 true 时处理其内容。评估结果可存储在 var
属性中。
简单用法:
<x:if select="$output//item">
文档至少包含一个 <item> 元素。
</x:if>
5.5. <x:forEach>
标签
<x:forEach>
遍历 XML 文档中的节点。XML 文档通过 select
属性指定。
类似 <c:forEach>
,有 begin
、end
和 step
属性。示例:
<ul class="items">
<x:forEach select="$output/items/item/name" var="item">
<li>项目名称: <x:out select="$item"/></li>
</x:forEach>
</ul>
5.6. <x:choose>
、<x:when>
和 <x:otherwise>
标签
<x:choose>
是实现 switch 或 if/else-if/else 逻辑的父标签,无属性,包含 <x:when>
和 <x:otherwise>
子标签。
<x:when>
:相当于 if/else-if,通过select
属性指定判断条件<x:otherwise>
:相当于 else/default,无属性
示例:
<x:choose>
<x:when select="$output//item/category = 'Sneakers'">
项目类别是运动鞋
</x:when>
<x:when select="$output//item/category = 'Heels'">
项目类别是高跟鞋
</x:when>
<x:otherwise>
未知类别。
</x:otherwise>
</x:choose>
5.7. <x:transform>
和 <x:param>
标签
<x:transform>
通过应用 XSL 样式表转换 JSP 中的 XML 文档。
待转换的 XML 文档/字符串通过 doc
属性指定,XSL 样式表通过 xslt
属性指定。
<x:param>
是其子标签,用于设置转换样式表中的参数。示例:
<c:import url="/items_xml" var="xslt"/>
<x:transform xml="${xmltext}" xslt="${xslt}">
<x:param name="bgColor" value="blue"/>
</x:transform>
6. SQL 标签
JSTL SQL 标签库提供执行关系数据库操作的标签。
使用前需添加:
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
支持 MySQL、Oracle 和 SQL Server 等数据库。
6.1. <sql:setDataSource>
标签
<sql:setDataSource>
定义 JDBC 配置变量。
配置变量存储在 driver
、url
、user
、password
和 dataSource
属性中。示例:
<sql:setDataSource var="dataSource" driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost/test" user="root" password=""/>
var
属性标识关联的数据库。
6.2. <sql:query>
标签
<sql:query>
执行 SQL SELECT 语句,结果存储在 var
属性指定的作用域变量中。典型用法:
<sql:query dataSource="${dataSource}" var="result">
SELECT * from USERS;
</sql:query>
sql
属性保存要执行的 SQL 命令。其他属性包括 maxRows
、startRow
和 dataSource
。
6.3. <sql:update>
标签
<sql:update>
类似 <sql:query>
,但只执行不需要返回值的 INSERT、UPDATE 或 DELETE 操作。示例:
<sql:update dataSource="${dataSource}" var="count">
INSERT INTO USERS(first_name, last_name, email) VALUES
('Grace', 'Adams', 'grace@example.com');
</sql:update>
var
属性存储受 SQL 语句影响的行数。
6.4. <sql:param>
标签
<sql:param>
是子标签,用于在 <sql:query>
或 <sql:update>
中为 SQL 语句的占位符提供值。示例:
<sql:update dataSource = "${dataSource}" var = "count">
DELETE FROM USERS WHERE email = ?
<sql:param value = "grace@example.com" />
</sql:update>
value
属性指定要提供的值。
6.5. <sql:dateParam>
标签
<sql:dateParam>
在 <sql:query>
或 <sql:update>
中为 SQL 语句的占位符提供日期时间值。示例:
<sql:update dataSource = "${dataSource}" var = "count">
UPDATE Users SET registered = ? WHERE email = ?
<sql:dateParam value = "<%=registered%>" type = "DATE" />
<sql:param value = "<%=email%>" />
</sql:update>
类似 <sql:param>
,但增加 type
属性,可选 date
、time
或 timestamp
。
6.6. <sql:transaction>
标签
<sql:transaction>
通过组合 <sql:query>
和 <sql:update>
创建事务操作。示例:
<sql:transaction dataSource = "${dataSource}">
<sql:update var = "count">
UPDATE Users SET first_name = 'Patrick-Ellis' WHERE
email='patrick@example.com'
</sql:update>
<sql:update var = "count">
UPDATE Users SET last_name = 'Nelson' WHERE
email ='patrick@example.com'
</sql:update>
<sql:update var = "count">
INSERT INTO Users(first_name, last_name, email)
VALUES ('Grace', 'Adams', 'grace@example.com');
</sql:update>
</sql:transaction>
确保所有数据库操作要么全部成功提交,要么在出错时全部回滚。
7. JSTL 函数
JSTL 函数是 JSP 中数据处理的工具集。虽然部分函数支持多种数据类型,但大多数专用于字符串操作。使用前需添加:
<%@ taglib prefix = "fn"
uri = "http://java.sun.com/jsp/jstl/functions" %>
7.1. fn:contains()
和 fn:containsIgnoreCase()
fn:contains()
检查字符串是否包含指定子串:
<c:set var = "string1" value = "This is first string"/>
<c:if test = "${fn:contains(string1, 'first')}">
<p>找到 'first'<p>
</c:if>
fn:containsIgnoreCase()
是不区分大小写的变体:
<c:if test = "${fn:containsIgnoreCase(string1, 'first')}">
<p>找到 'first'<p>
</c:if>
<c:if test = "${fn:containsIgnoreCase(string1, 'FIRST')}">
<p>找到 'FIRST'<p>
</c:if>
7.3. fn:endsWith()
函数
fn:endsWith()
检查字符串后缀是否匹配指定子串:
<c:if test = "${fn:endsWith(string1, 'string')}">
<p>字符串以 'string' 结尾<p>
</c:if>
7.4. fn:escapeXml()
函数
fn:escapeXml()
转义输入字符串中的 XML 标记:
<p>${fn:escapeXml(string1)}</p>
7.5. fn:indexOf()
函数
fn:indexOf()
返回子串首次出现的索引:
<p>索引位置: ${fn:indexOf(string1, "first")}</p>
7.6. fn:join()
函数
fn:join()
将数组所有元素连接为单个字符串:
<c:set var = "string3" value = "${fn:split(string1, ' ')}" />
<c:set var = "string4" value = "${fn:join(string3, '-')}" />
7.7. fn:length()
函数
fn:length()
返回集合元素数或字符串字符数:
<p>长度: ${fn:length(string1)}</p>
7.8. fn:replace()
函数
fn:replace()
替换字符串中所有出现的子串:
<c:set var = "string3" value = "${fn:replace(string1, 'first', 'third')}" />
7.9. fn:split()
函数
fn:split()
按指定分隔符分割字符串:
<c:set var = "string3" value = "${fn:split(string1, ' ')}" />
7.10. fn:startsWith()
函数
fn:startsWith()
检查字符串前缀是否匹配指定子串:
<c:if test = "${fn:startsWith(string1, 'This')}">
<p>字符串以 'This' 开头</p>
</c:if>
7.11. fn:substring()
函数
fn:substring()
从源字符串创建子串:
<c:set var = "string3" value = "${fn:substring(string1, 5, 15)}" />
7.12. fn:substringAfter()
函数
fn:substringAfter()
返回子串首次出现后的字符串部分:
<c:set var = "string3" value = "${fn:substringAfter(string1, 'is')}" />
7.13. fn:substringBefore()
函数
fn:substringBefore()
返回子串首次出现前的字符串部分:
<c:set var = "string3" value = "${fn:substringBefore(string1, 'is')}" />
7.14. fn:toLowerCase()
函数
fn:toLowerCase()
将字符串转为小写:
<c:set var = "string3" value = "${fn:toLowerCase(string1)}" />
7.15. fn:toUpperCase()
函数
fn:toUpperCase()
将字符串转为大写:
<c:set var = "string3" value = "${fn:toUpperCase(string1)}" />
7.16. fn:trim()
函数
fn:trim()
移除字符串首尾空白:
<c:set var = "string1" value = "This is first String "/>
9. 总结
本文全面介绍了 JSTL 各类标签及其使用方法。通过合理运用这些标签,可以显著提升 JSP 开发效率,减少脚本代码,增强可维护性。
代码示例可在 GitHub 获取。