JSTL(JSP Standard Tag Library)把迭代、条件、格式化、XML、数据库访问这类常用能力收成一套标签。EL 负责把变量从各 Scope 里取出来,两者经常一起写,JSP 才不像一堆脚本碎片。
标签库分四块:核心 core、格式化、SQL、XML。页面上先把 jar 放进 WEB-INF/lib,再在 JSP 头引入 taglib。
下面按环境搭建 → EL → 核心标签 → 函数库的顺序把原笔记过一遍。
一、JSTL 简介和环境配置
1. 什么是 JSTL
JSP 标准标签库是一套实现 Web 应用常见功能的定制标记库,包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。
2. 为什么要用 JSTL
-
页面代码可复用:基于标签库,重复率高的块能抽出来。
-
3. JSTL 环境搭建
下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
文件:jakarta-taglibs-standard-1.1.2.zip(2004-10-25,933K)。解压后 lib 里有 standard.jar 和 jstl.jar。
不要只靠「右击项目 → Build Path」加 link:项目挪位置或 jar 删了就会报错。推荐把 jar 复制进 WebRoot\WEB-INF\lib,再选中 jar → 右键 → Build Path → Add to Build Path,让包跟着项目走。
JSP 引入核心库:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
二、EL 表达式
JSTL 标签的 value 可以输出常量和变量。常量直接写,变量用 EL 取:
<c:out value="20"></c:out>
<c:out value="${age}"></c:out>

1. 什么是 EL
全名 Expression Language,常配合 JSTL,让 JSP 更直观:
普通写法:
<%=session.getValue("name")%>
EL 写法:
<c:out value="${sessionScope.name}" />
格式:美元符 $ 定界,内容写在花括号里,即 ${表达式}。注意 . 和 []:

2. EL 变量

<c:out value="${temp}"></c:out>
没限定范围时,会按默认从小到大搜索;找不到则输出空字符串。

3. EL 隐式对象

4. EL 运算符

empty 举例:对 null 和空字符串都返回 true;有内容则 false。
<% String username = null; request.setAttribute("username", username); %>
<c:out value="${empty username}"></c:out>
三、JSTL 核心标签库
核心库共 13 个标签,分成 4 类。使用前务必在 JSP 头加入 taglib。
| 分类 |
标签 |
| 表达式控制 |
out、set、remove、catch |
| 流程控制 |
if、choose、when、otherwise |
| 循环 |
forEach、forTokens |
| URL 操作 |
import、url、redirect |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
1. out
<c:out value="23" default="20"></c:out>
<c:out value="${age}" default="20"></c:out>
2. set
把值存进 page / request / session / application;也可以给 JavaBean 属性赋值:
<c:set var="age" value="23" scope="session" />
<%-- <c:set var="age" scope="session">23</c:set> --%>
<h1><c:out value="三、set标签给javaBean属性赋值"></c:out></h1>
<jsp:useBean id="person" class="com.ittx.entity.Person" scope="page" />
<c:set target="${person}" property="name" value="麻子"></c:set>
<c:out value="${person.name}" />
<%-- <jsp:setProperty property="name" name="person" value="小明11"/> --%>
<%-- <jsp:getProperty property="name" name="person" /> --%>
3. remove
只能删掉某个变量,不能删对象的某个属性。var 必选,scope 可选。
<c:set var="firstName" value="小明"></c:set>
<c:remove var="firstName" />
4. catch
把容易出错的 JSTL 逻辑包起来:
<c:catch var="error">
<c:set target="user" property="firstName" value="lili"></c:set>
</c:catch>
<c:out value="${error}"></c:out>
5. if
test 放判断条件(一般用 EL),var 存 true/false,scope 指定存放范围。语法:<c:if test="" var="" scope=""></c:if>。按成绩分等级:
<c:if test="${param.score >= 90}" var="result">
<c:out value="成绩优异!"></c:out>
</c:if>
<c:out value="${result}"></c:out>
6. choose / when / otherwise
c:choose 作为父标签包住 c:when 和 c:otherwise:
<c:choose>
<c:when test="${param.score<=100 && param.score>=60 }">
<c:out value="及格"></c:out>
</c:when>
<c:when test="${param.score<60 && param.score>=0 }">
<c:out value="不及格"></c:out>
</c:when>
<c:otherwise>
<c:out value="请检查你的输入!"></c:out>
</c:otherwise>
</c:choose>
7. forEach 和 forTokens
<h1>forEach</h1>
<%
ArrayList<String> lists = new ArrayList();
lists.add("one");
lists.add("two");
lists.add("three");
lists.add("four");
session.setAttribute("list", lists);
%>
<c:forEach items="${sessionScope.list}" var="item" begin="1" end="3">
<c:out value="${item}"/>
</c:forEach>
<br><hr>
<h1>forTokens</h1>
<%
String noUrl = "login.jsp;login.do;loginout.jsp;register.jsp";
session.setAttribute("noUrl", noUrl);
%>
<c:forTokens items="${sessionScope.noUrl}" delims=";" var="item">
<c:out value="${item}"/><br>
</c:forTokens>
8. URL 操作标签
import、redirect、url:
<%-- <jsp:include page="./index.jsp"></jsp:include> --%>
<c:import url="http://www.baidu.com" charEncoding="utf-8"></c:import>
<br><hr>
<h1>redirect</h1>
<%-- <c:redirect url="./index.jsp">
<c:param name="userName" value="10"></c:param>
</c:redirect> --%>
<br><hr>
<h1>url</h1>
<c:url var="main" value="http://192.168.5.3:8080/Jstl/index.jsp">
<c:param name="userName" value="11"></c:param>
<c:param name="passWord" value="123456"></c:param>
</c:url>
<c:out value="${main}"></c:out>
<a href="${main}">首页</a>
四、JSTL 函数
配合 functions 库。页面头同时引入:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
1. contains、startsWith、endsWith
contains 判断字符串是否包含子串,返回 boolean。startsWith / endsWith 看头尾。
2. escapeXml、indexOf
<c:out value="“Hello World”字符串中是否包含“Hello”?${fn:contains('Hello World','Hello')}"></c:out>
<hr>
<c:out value="“Hello World”字符串中是否包含“ABCD”?${fn:contains('Hello World','ABCD')}"></c:out>
<hr>
<c:out value="“Hello World”字符串中是否包含“hello”(忽略大小写)?${fn:containsIgnoreCase('Hello World','hello')}"></c:out>
<hr>
<c:out value="“Hello”是否在“Hello World”字符串开头?${fn:startsWith('Hello World','Hello')}"></c:out>
<hr>
<c:out value="“world”是否在“Hello World”字符串尾部?${fn:endsWith('Hello World','world')}"></c:out>
<c:out value="${fn:indexOf('helloworld','java')}"></c:out>
<c:out value="${fn:escapeXml('<book>书</book>')}"></c:out>
<c:out value="<book>书</book>"></c:out>

一句话总结:EL 用 ${} 按 Scope 从小到大找变量;核心标签管输出、分支、循环和 URL;字符串判断再引入 fn 前缀。