EL和JSTL
在JSP开发中,为了获取Servlet域对象中存储的数据,经常需要书写很多Java代码,这样的话会使JSP页面混乱。为了降低JSP页面的复杂度,增强代码的重用性,Sun公司制定了一套标准标签库JSTL,同时为了获取Servlet域对象中存储的数据,JSP 2.0规范还提供了EL(表达式语言),大大降低了开发的难度。下面将针对EL以及JSTL标签库进行详细讲解。
1.EL
01. EL基本语法
概念:
EL全称为Expression Language,即表达式语言。它是JSP 2.0引入的一个新内容。EL可以简化JSP开发中的对象引
用,从而规范页面代码,增加程序的可读性及可维护性。EL为不熟悉Java语言页面开发的人员提供了一个开发JavaWeb应用
的新途径。
语法:
EL的语法非常简单,都是以“${”符号开始,以“}”符号结束的,具体格式如下:
${表达式}
“${表达式}”中的表达式必须符合EL语法要求。
小提示:
由于EL的语法以“${" 开头,如果在JSP网页中要显示“${"字符串,必须在前面加上“\”符号,即“\${",或者写
成“${${}", 也就是用表达式输出“${" 符号。
@WebServlet(name = "ElServlet" , value = "/ElServlet")
public class ElServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("username", "zhangsan");
req.setAttribute("password", "123456");
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/admin.jsp");
requestDispatcher.forward(req,resp);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Jsp写法:<br>
用户:<%=request.getAttribute("username") %>
密码:<%=request.getAttribute("password") %>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Jsp写法:<br>
用户:<%=request.getAttribute("username") %>
密码:<%=request.getAttribute("password") %>
<br >
el写法:
用户:${username}
密码:${password}
<br >
</body>
</html>
由上图中可知,使用EL同样可以成功获取Servlet中存储的数据,但EL明显简化了JSP页面的书写,使程序简洁易维
护。另外,当域对象里面的值不存在时,使用EL获取域对象里面的值时返回空字符串;而使用Java方式获取时,如果返回值
是null,会报空指针异常,所以在实际开发中推荐使用EL的方式获取域对象中存储的数据。
EL基本语法的特点:
(1)EL可以与JavaScript语句结合使用。
(2)EL可以自动进行类型转换。如果想通过EL获取两个字符串数值(如number1和number2)的和,可以直接通过“+”符号
进行连接(如$ {number1+number2})。
(3)EL不仅可以访问一般变量,还可以访问JavaBean中的属性、嵌套属性和集合对象。
(4)在EL中,可以执行算术运算、逻辑运算、关系运算和条件运算等。
(5)在EL中,可以获取pageContext对象,进而获取其他内置对象。
(6)在使用EL进行除法运算时,如果除数为0,则返回表示无穷大的Infinity,而不返回错误。
(7)在EL中,可以访问JSP的作用域(request、 session、 application 以及page)。
02. EL中的标识符
在EL中,经常需要使用一些符号标记一些名称,如变量名、自定义函数名等,这些符号被称为标识符。EL中的标识符可以由
任意的大小写字母、数字和下划线组成,为了避免出现非法的标识符,在定义标识符时还需要遵循以下规范:
(1)不能以数字开头。
(2)不能是EL中的关键字,如and、or、gt等。
(3)不能是EL隐式对象,如pageContext。
(4)不能包含单引号(')、双引号(")、减号(-)和正斜线(/)等特殊字符。
03. EL中的关键字
关键字就是编程语言里事先定义好并赋予了特殊含义的单词,和其他语言一样,EL中也定义了许多关键字,如false、not
等。EL中所有的关键字如下所示:
and eq gt true instanceof
or ne le false empty
not lt ge null div mod
04. EL中的变量
EL中的变量就是一个基本的存储单元,EL中的变量不用事先定义就可以直接使用。EL可以将变量映射到一个对象上,具体示
例如下所示: ${product}
在上述示例中,product就是一个变量,通过表达式${product}就可以访问变量product的值。
05. EL中的常量
EL中的常量—布尔常量
布尔常量用于区分一个事物的正反两面,它的值只有两个,分别是true和false。
EL中的常量—整型常量
整型常量与Java中的十进制的整型常量相同,它的取值范围是Java语言中定义的常量Long.MIN_VALUE到
Long.MAX_VALUE之间,即(-2)∧63~2∧63-1之间的整数。
EL中的常量—浮点数常量
浮点数常量用整数部分加小数部分表示,也可以用指数形式表示,例如,1.2E4和1.2都是合法的浮点数常量。浮点数
常量的取值范围是Java语言中定义的常量Double.MIN_VALUE到Double.MAX_VALUE之间,即4.9E-324~1.8E308之间的浮
点数。
EL中的常量—字符串常量
字符串常量是用单引号或双引号引起来的一连串字符。由于字符串常量需要用单引号或双引号引起来,所以字符串本身
包含的单引号或双引号需要用反斜杠(\)进行转义,即用“\'”表示字面意义上的单引号,用“\"”表示字面意义上的双引
号。如果字符串本身包含反斜杠(\),也要进行转义,即用“\\”表示字面意义上的一个反斜杠。
需要注意的是,只有字符串常量用单引号引起来时,字符串本身包含的单引号才需要进行转义,而双引号不必进行转
义,例如,'ab\'4c"d5\\e'表示的字符串是ab'4c"d5\e;只有字符串常量用双引号引起来时,字符串本身包含的双引号才
需要进行转义,而单引号不必转义,例如"ab'4c\"d5\\e"表示的字符串是ab'4c"d5\e。
EL中的常量—Null常量
Null常量用于表示变量引用的对象为空,它只有一个值,用null表示。
06. EL访问数据
EL中的运算符—点运算符(.)
EL中的点运算符,用于访问JSP页面中某些对象的属性,如JavaBean对象中的属性、List集合中的属性、Array数组
中的属性等,其用法示例如下: ${customer.name}
在上述语法格式中,表达式${customer.name}中点运算符的作用就是访问customer对象中的name属性。
EL中的运算符—方括号运算符([])
EL中的中括号运算符与点运算符的功能相同,都用于访问JSP页面中某些对象的属性,当获取的属性名中包含一些特殊
符号,如“-”或“?”等非字母或数字的符号,就只能使用中括号运算符访问该属性。中括号运算符的用法示例如下:
${user["My-Name"]}
EL中的运算符在实际中的应用
(1)点运算符和方括号运算符在某种情况下可以互换,如${student.name}等价于
${student["name"]}。
(2)中括号运算符还可以访问List集合或数组中指定索引的某个元素,如表达式
${users[0]}用于访问集合或数组中第一个元素。
(3)中括号运算符和点运算符可以相互结合使用,例如,表达式${users[0].userName}
可以访问集合或数组中的第一个元素的userName属性。
07. EL中的运算符
算术运算符
算术运算符 | 说明 | 算术表达式 | 结果 |
---|---|---|---|
+ | 加 | ${10+2} | 12 |
- | 减 | ${10-2} | 8 |
* | 乘 | ${10*2} | 20 |
/(或div) | 除 | 10 / 4 或 {10/4}或 10/4或{10 div 2} | 2.5 |
%(或mod) | 取模(取余) | KaTeX parse error: Expected '}', got 'EOF' at end of input: {10%4}或{10 mod 2} | 2 |
EL中的算术运算符用于对整数和浮点数的值进行算术运算。这些运算符相对来说比较简单。在使用这些运算符时需要注意两个问题。
(1)“-”运算符即可以作为减号,也可以作为负号。
(2)“/”或“div”运算符在进行除法运算时,商为小数。
算术运算符的小提示
EL的“+”运算符与Java的“+”运算符不同,它不能实现两个字符串之间的连接,如果使用该运算符连接两个不可以转换为数值型的字符串,将抛出异常;如果使用该运算符连接两个可以转换为数值型的字符串,EL会自动将这两个字符串转换为数值型,再进行加法运算。
比较运算符
EL中的比较运算符用于比较两个操作数的大小,操作数可以是各种常量、EL变量或EL表达式,所有的比较运算符执行的结果都是布尔类型。
比较运算符 | 说明 | 算术表达式 | 结果 |
---|---|---|---|
==(或eq) | 等于 | 10 = = 2 或 {10==2}或 10==2或{10 eq 2} | false |
!=(或ne) | 不等于 | 10 ! = 2 或 {10!=2}或 10!=2或{10 ne 2} | true |
<(或lt) | 小于 | 10 < 2 或 {10<2}或 10<2或{10 lt 2} | false |
>(或gt) | 大于 | 10 > 2 或 {10>2}或 10>2或{10 gt 2} | true |
<=(或le) | 小于等于 | 10 < = 2 或 {10<=2}或 10<=2或{10 le 2} | false |
>=(或ge) | 大于等于 | 10 > = 2 或 {10>=2}或 10>=2或{10 ge 2} | true |
比较运算符的注意点
(1)比较运算符中的“==”是两个等号,千万不可只写一个等号。
(2)为了避免与JSP页面的标签产生冲突,对于后4种比较运算符,EL中通常使用上表中括号内的表示方式,例如,使用“lt”代替“<”运算符,如果运算符后面是数字,在运算符和数字之间至少要有一个空格,例如
1
l
t
2
,
但
后
面
如
果
有
其
他
符
号
时
则
可
以
不
加
空
格
,
例
如
{1lt 2},但后面如果有其他符号时则可以不加空格,例如
1lt2,但后面如果有其他符号时则可以不加空格,例如{1lt(1+1)}。
逻辑运算符
EL中的逻辑运算符用于对结果为布尔类型的表达式进行运算,运算的结果仍为布尔类型。
比较运算符 | 说明 | 算术表达式 | 结果 |
---|---|---|---|
逻辑运算符 | 说明 | 算术表达式 | 结果 |
&&(and) | 逻辑与 | KaTeX parse error: Expected '}', got '&' at position 6: {true&̲&false}或{true and false} | false |
||(or) | 逻辑或 | f a l s e ∥ ∥ t r u e 或 {false\|\|true}或 false∥∥true或{false or true} | true |
逻辑运算符的注意点
需要注意的是,在使用&&运算符时,如果有一个表达式结果为false,则整个表达式结果必为false;在使用||运算符时,如果有一个表达式的结果为true,则整个表达式结果必为true。
empty运算符
在EL中,判断对象是否为空,可以通过empty运算符实现,该运算符是一个前缀(prefix)运算符, 即empty运算符位于操作数前方,用来确定一个对象或变量是否为null或空。empty运算符的语法格式如下: ${empty expression}
在上述语法格式中,expression用于指定要判断的变量或对象。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<% request.setAttribute("user" , ""); %>
<% request.setAttribute("user1" , null); %>
${empty user}
${empty user1}
</body>
</html>
由上述代码可知一个变量或对象为null 或空,代表的意义是不同的。null 表示这个变量没有指明任何对象,而空表示这个变量所属的对象内容为空,例如,空字符串、空的数组或者空的List容器。
条件运算符
EL中条件运算符(?:)用于执行某种条件判断,它类似于Java语言中的if-else语句,其语法格式如下: ${A?B:C}
在上述语法格式中,表达式A的计算结果为布尔类型,如果表达式A的计算结果为true,就执行表达式B,并返回B的值作为整个表达式的结果;如果表达式A的计算结果为false,就执行表达式C,并返回C的值作为整个表达式的结果。例如,表达式${(1==2)?3:4}的结果就是4。
“()”运算符
EL中的小括号用于改变其他运算符的优先级,例如,表达式 a ∗ b + c , 正 常 情 况 下 会 先 计 算 a ∗ b 的 积 , 然 后 再 将 计 算 的 结 果 与 c 相 加 , 如 果 在 这 个 表 达 式 中 加 一 个 小 括 号 运 算 符 , 将 表 达 式 修 改 为 {a*b+c},正常情况下会先计算a*b的积,然后再将计算的结果与c相加,如果在这个表达式中加一个小括号运算符,将表达式修改为 a∗b+c,正常情况下会先计算a∗b的积,然后再将计算的结果与c相加,如果在这个表达式中加一个小括号运算符,将表达式修改为{a*(b+c)},则会先计算b与c的和,再将计算的结果与a相乘。
“()”运算符的优先级
EL中的运算符都有不同的运算优先级,当EL中包含多种运算符时,它们必须按照各自优先级的大小进行运算。EL中运算符的优先级如下表所示。
优先级 | 运算符 |
---|---|
1 | [ ] . |
2 | ( ) |
3 | -(unary) not ! empty |
4 | * / div % mod |
5 | + -(binary) |
6 | < > <= >= lt gt le ge |
7 | == != eq ne |
8 | && and |
9 | || or |
10 | ?: |
注意:在应用EL取值时,没有数组的下标越界,没有空指针异常,没有字符串的拼接。
2.EL隐式对象
EL隐式对象
为了能够获得Web应用程序中的相关数据,EL提供了11个隐式对象,这些对象类似于JSP的内置对象,可以直接通过对
象名进行各种操作。在EL的隐式对象中,除PageContext是JavaBean对象,对应于javax.servlet.jsp.PageContext类
型外,其他的隐式对象都对应于java.util.Map类型。这些隐式对象可以分为页面上下文对象、访问作用域范围的隐式对象
和访问环境信息的隐式对象3种。
隐式对象名称 | 描 述 |
---|---|
pageContext | 对应于JSP页面中的pageContext对象 |
pageScope | 代表page域中用于保存属性的Map对象 |
requestScope | 代表request域中用于保存属性的Map对象 |
sessionScope | 代表session域中用于保存属性的Map对象 |
applicationScope | 代表application域中用于保存属性的Map对象 |
param | 表示一个保存了所有请求参数的Map对象 |
paramValues | 表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个String类型数组 |
header | 表示一个保存了所有http请求头字段的Map对象 |
headerValues | 表示一个保存了所有http请求头字段的Map对象,返回String类型数组 |
cookie | 用于获取使用者的cookie值,cookie的类型是Map |
initParam | 表示一个保存了所有Web应用初始化参数的Map对象 |
在上表列举的隐式对象中,pageContext可以获取其他10个隐式对象,pageScope、requestScope、
sessionScope、applicationScope是用于获取指定域的隐式对象;param和paramValues是用于获取请求参数的隐式对象,header和headerValues是用于获取HTTP请求消息头的隐式对象;cookie是用于获取Cookie信息的隐式对象;
initParam是用于获取Web应用初始化信息的隐式对象。
01. pageContext对象
为了获取JSP页面的隐式对象,可以使用EL中的pageContext隐式对象。pageContext隐式对象用法示例代码如下:
${pageContext.response.characterEncoding}
pageContext对象用于获取response对象中的characterEncoding属性。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
请求URI为:${pageContext.request.requestURI} <br />
Content-Type响应头:${pageContext.response.contentType} <br />
服务器信息为:${pageContext.servletContext.serverInfo} <br />
Servlet注册名为:${pageContext.servletConfig.servletName} <br />
</body>
</html>
需要注意的是,不要将EL中的隐式对象与JSP中的隐式对象混淆,只有pageContext对象是它们所共有的,其他隐式对象则毫不相关。
02. Web域相关对象
在EL中提供了4 个用于访问作用域范围的隐式对象,即pageScope、requestScope、 sessionScope和
applicationScope。应用这4个隐式对象指定所要查找的标识符的作用域后,系统将不再按照默认的顺序(page、
Request、session及application)查找相应的标识符。它们与JSP中的page、request、session及application内置对
象类似,只不过这4个隐式对象只能用于获取指定范围内的属性值,而不能获取其他相关信息。
pageScope、requestScope、 sessionScope和applicationScope4个隐式对象都可以通过setAttribute()方法存
储属性,通过getAttribute()方法获取属性。
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2022/3/26
Time: 13:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<% pageContext.setAttribute("userName","千峰"); %>
<% request.setAttribute("bookName", "Java Web"); %>
<% session.setAttribute("userName", "千峰"); %>
<% application.setAttribute("bookName", "Java 基础"); %>
表达式\${pageScope.userName}的值为:${pageScope.userName} <br />
表达式\${requestScope.bookName}的值为:${requestScope.bookName} <br />
表达式\${sessionScope.userName}的值为:${sessionScope.userName} <br />
表达式\${applicationScope.bookName}的值为:${applicationScope.bookName} <br />
表达式\${userName}的值为:${userName}
</body>
</html>
03. 访问环境信息的隐式对象
获取客户端传递的请求参数
在JSP页面中,经常需要获取客户端传递的请求参数,为此,EL提供了param和paramValues两个隐式对象,这两个隐
式对象专门用于获取客户端访问JSP页面时传递的请求参数。
param对象的语法
param对象用于获取请求参数的某个值,它是Map类型,与request.getParameter()方法相同,在使用EL获取参数
时,如果参数不存在,返回的是空字符串,而不是null。param对象的语法格式比较简单,具体示例如下:
${param.num}
paramValues对象的语法
如果一个请求参数有多个值,可以使用paramValues对象获取请求参数的所有值,该对象返回请求参数所有值组成的
数组,如果要获取某个请求参数的第一个值,可以使用如下代码:
${paramValues.nums[0]}
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2022/3/26
Time: 14:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/param.jsp">
num1:<input type="text" name="num1"><br />
num2:<input type="text" name="num"><br />
num3:<input type="text" name="num"><br /> <br />
<input type="submit" value="提交" />
<input type="submit" value="重置" /><hr />
num1: ${param.num1} <br />
num2: ${paramValues.num[0]} <br />
num3: ${paramValues.num[1]} <br />
</form>
</body>
</html>
需要注意的是,如果一个请求参数有多个值,那么在使用param获取请求参数时,则返回请求参数的第一个值。
04. Cookie对象
在JSP开发中,经常需要获取客户端的Cookie信息,为此,在EL中,提供了Cookie隐式对象,该对象是一个集合了所
有Cookie信息的Map集合,Map集合中元素的键为各个Cookie的名称,值则为对应的Cookie对象。cookie对象用法示例如
下:
获取cookie对象的信息:${cookie.userName}
获取cookie对象的名称:${cookie.userName.name}
获取cookie对象的值:${cookie.userName.value}
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2022/3/26
Time: 14:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Cookie对象的信息:<br />
${cookie.userName } <br />
Cookie对象的名称和值:<br />
${cookie.userName.name }=${cookie.userName.value }
<% response.addCookie(new Cookie("userName", "千峰")); %>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XkOyE7Rw-1648284385110)(EL和JSTL.assets/1648275544406.png)]
由上图可知,浏览器窗口中显示了获取到的Cookie信息,这是因为第一次访问服务器时,服务器会向浏览器回写一个Cookie,此时的Cookie信息是存储在浏览器中的,当刷新浏览器,第二次访问cookie.jsp页面时,由于浏览器中已经存储了名为userName的Cookie信息,浏览器会将此Cookie信息一同发送给服务器,这时使用表达式 c o o k i e . u s e r N a m e . n a m e 和 {cookie.userName.name }和 cookie.userName.name和{cookie.userName.value }便可以获取Cookie的名称和值。
05. initParam对象
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>author</param-name>
<param-value>mio</param-value>
</context-param>
</web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${initParam.author}
</body>
</html>
3.JSTL
从JSP 1.1规范开始,JSP就支持使用自定义标签,使用自定义标签大大降低了JSP页面的复杂度,同时增强了代码的
重用性。为此,许多Web应用厂商都制定了自身应用的标签库,然而同一功能的标签由不同的Web应用厂商制定可能是不同
的,这就导致市面上出现了很多功能相同的标签,令网页制作者无从选择,为了解决这个问题,Sun公司制定了一套标准标
签库(JavaServer Pages Standard Tag Library),简称JSTL。
虽然JSTL叫做标准标签库,但实际上它是由5个功能不同的标签库组成。这5个标签库分别是核心标签库、国际化/格式
化标签库、SQL标签库、XML标签库和函数标签库。在使用这些标签库之前,必须在JSP页面的顶部使用<%@ taglib%>指令
定义引用的标签库和访问前缀。
JSTL的标签库—核心标签库
使用核心标签库的taglib指令格式如下
<%@ taglib prefix="c" url="http://java.sun.com/jsp/jstl/core" %>
核心标签库主要用于完成JSP页面的常用功能,包括JSTL的表达式标签、URL标签、流程控制标签。例如,用于输出文
本内容的<c:out>标签、用于条件判断的<c:if>标签、用于迭代循环的<c:forEach>标签等。
JSTL的标签库—格式标签库
使用格式标签库的taglib指令格式如下:
<%@ taglib prefix "fmt" url="http://java.sun.com/jsp/jstl/fmt"%>
国际化/格式化标签库,它包含实现Web应用程序的国际化标签和格式化标签。例如,设置JSP页面的本地信息、设置
JSP页面的时区、使日期按照本地格式显示等。
JSTL的标签库—SQL标签库
使用SQL标签库的taglib指令格式如下:
<%@ taglib prefix="sql" url="http://java.sun.com/jsp/jstl/sql" %>
SQL标签库,它包含了用于访问数据库和操作数据库的标签。例如,获取数据库连接、从数据库表中检索数据等。由于
在软件分层开发模型中,JSP页面仅作为显示层,一般不会在JSP页面中直接操作数据库,所以,JSTL中提供的这套标签库
不经常使用。
JSTL的标签库—XML标签库
使用XML标签库的taglib指令格式如下:
<%@ taglib prefx="xml" url="http://java.sun.com/jsp/jstl/xml" %>
XML文档的标签库,它包含对XML文档中的数据进行操作的标签。例如,解析XML文件、输出XML文档中的内容,以及迭
代处理XML文档中的元素。XML广泛应用于Web开发,使用XML标签库处理XML文档更加简单方便。
JSTL的标签库—函数标签库
使用函数标签库的taglib指令格式如下:
<%@ taglib prefix= "fn" url="http://java.sun.com/jsp/jstl/functions"%>
函数标签库,它提供了一套自定义EL函数,包含了JSP网页制作者经常要用到的字符串操作。例如,提取字符串中的子
字符串、获取字符串的长度等。
JSTL的下载和使用
jstllib包jstllib包jstllib包-Java文档类资源-CSDN文库
在上图中的【URI】选项中填入http://java.sun.com/jsp/jstl/core,在【File】选项中找到解压文件jakarta-taglibs-standard-1.1.2的tld目录下的c.tld文件,单击【OK】按钮完成导入。至此,JSTL安装配置完成,在chapter07项目中就可以使用JSTL标签库了。
测试JSTL
由于在测试的时候需要使用<c:out>标签,所以需要使用taglib指令导入Core标签库,具体代码如下:
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
taglib指令的uri属性用于指定引入标签库描述符文件的URI,prefix属性用于指定引入标签库描述符文件的前缀,在JSP文件中使用这个标签库中的某个标签时,都需要使用这个前缀。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:out value="Hello World!"></c:out>
</body>
</html>
4.JSTL中的Core标签库
01. <c:out>标签
在JSP页面中,最常见的操作就是向页面输出一段文本信息,为此,Core标签库提供了<c:out>标签,该标签可以将一
段文本内容或表达式的结果输出到客户端。如果<c:out>标签输出的文本内容中包含需要进行转义的特殊字符,例如>、<、
&、'、" 等,<c:out>标签会默认对它们进行HTML编码转换后再输出。
<c:out>标签有两种语法格式,具体如下:
语法1:没有标签体的情况
<c:out value="value" [default="defaultValue"]
[escapeXml="{true|false}"]/>
语法2:有标签体的情况
<c:out value="value" [escapeXml="{true|false}"]>
defaultValue
</c:out>
<c:out>标签的语法格式中,没有标签体的情况,需要使用default属性指定默认值,有标签体的情况,在标签体中指定输
出的默认值。<c:out>标签有多个属性,下面对这些属性进行讲解。
(1)value属性用于指定输出的文本内容。
(2)default属性用于指定当value属性为null时所输出的默认值,该属性是可选的(中括号中的属性都是可选的)。
(3)escapeXml属性用于指定是否将>、<、&、'、" 等特殊字符进行HTML编码转换后再进行输出,默认值为true。
需要注意的是,只有当value属性值为null时,<c:out>标签才会输出默认值,如果没有指定默认值,则默认输出空字符
串。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--第1个out标签 --%>
userName属性的值为:
<c:out value="${param.username}" default="unknown"/> <br />
<%--第2个out标签 --%>
userName属性的值为:
<c:out value="${param.username}">
unknown
</c:out>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--第1个out标签 --%>
userName属性的值为:
<c:out value="${param.username}" default="unknown"/> <br />
<%--第2个out标签 --%>
userName属性的值为:
<c:out value="${param.username}">
unknown
</c:out>
<c:out value="${param.username }" escapeXml="false">
<meta http-equiv="refresh"
content="0;url=http://www.baidu.com" />
</c:out>
</body>
</html>
<c:remove>移除标签
<c:remove>标签用于移除指定的JSP范围内的变量,其语法格式如下:
<c:remove var="name" [scope=”范围”]/>
<c:remove>标签参数含义如下:
var:用于指定要移除的变量名。
scope:用于指定变量的有效范围,可选值有page、request、session和application,默认值为page。如果在该标签中
没有指定变量的有效范围,那么将分别在page、request、 session 和application的范围内查找要移除的变量并移除。
例如,在一个页面中,存在不同范围的两个同名变量,当不指定范围时移除该变量,这两个范围内的变量都将被移除。因
此,在移除变量时,最好指定变量的有效范围。
02. 流程控制标签
流程控制在程序中会根据不同的条件执行不同的代码产生不同的运行结果,使用流程控制可以处理程序中的逻辑问题。在JSTL中包含<c:if>、<c:choose> 等流程控制标签可以实现程序的流程控制。
<c:if>标签
在程序开发中,经常需要使用if语句进行条件判断,如果要在JSP页面中进行条件判断,就需要使用Core标签库提供的
<c:if>标签,该标签专门用于完成JSP页面中的条件判断,它有两种语法格式。
语法1:没有标签体的情况
<c:if test="testCondition" var="result"
[scope="{page|request|session|application}"]/>
语法2:有标签体的情况,在标签体中指定要输出的内容
<c:if test="testCondition" var="result"
[scope="{page|request|session|application}"]>
body content
</c:if>
在<c:if>标签格式中,可以看到<c:if>标签有三个属性,下面对这三个属性分别进行讲解。
test属性用于设置逻辑表达式。
var属性用于指定逻辑表达式中变量的名字。
scope属性用于指定var变量的作用范围,默认值为page。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:set value="1" var="visitCount" property="visitCount" />
<c:if test="${visitCount==1 }">
This is you first visit. Welcome to the site!
</c:if>
</body>
</html>
<c:choose>、<c:when>和<c:otherwise>标签
在程序开发中不仅需要使用if条件语句,还经常会使用if-else语句,为了在JSP页面中也可以完成同样的功能,Core
标签库提供了<c:choose>标签,该标签用于指定多个条件选择的组合边界,它必须与<c:when>、<c:otherwise>标签一起
使用。
<c:choose>标签
<c:choose>标签没有属性,在它的标签体中只能嵌套一个或多个<c:when>标签,零个或一个<c:otherwise>标签,
并且同一个<c:choose>标签中所有的<c:when>子标签必须出现在<c:otherwise>子标签之前,其语法格式如下:
<c:choose>
Body content(<when> and <otherwise> subtags)
</c:choose>
<c:when>标签
<c:when>标签只有一个test属性,该属性的值为布尔类型。test属性支持动态值,其值可以是一个条件表达式,如果
条件表达式的值为true,就执行这个<c:when>标签体的内容,其语法格式如下:
<c:when test="testCondition">
Body content
</c:when>
<c:otherwise>标签
<c:otherwise>标签没有属性,它必须作为<c:choose>标签最后分支出现,当所有的<c:when>标签的test条件都不
成立时,才执行和输出<c:otherwise>标签体的内容,其语法格式如下:
<c:otherwise>
conditional block
</c:otherwise>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:choose>
<c:when test="${empty param.username}">
unKnown user.
</c:when>
<c:when test="${param.username=='itcast' }">
${ param.username} is manager.
</c:when>
<c:otherwise>
${ param.username} is employee.
</c:otherwise>
</c:choose>
</body>
</html>
03. 循环标签
<c:forEach>标签
在JSP页面中,经常需要对集合对象进行循环迭代操作,为此,Core标签库提供了一个<c:forEach>标签,该标签专门
用于迭代集合对象中的元素,如Set、List、Map、数组等,并且能重复执行标签体中的内容。
<c:forEach>标签有两种语法格式,具体如下:
语法1:迭代包含多个对象的集合
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
语法2:迭代指定范围内的集合
<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin"
end="end" [step="step"]>
body content
</c:forEach>
<c:forEach>标签有多个属性。下面对这些属性分别进行讲解。
var属性:用于将当前迭代到的元素保存到page域中的名称。
items属性:用于指定将要迭代的集合对象。
varStatus属性:用于指定将当前迭代状态信息的对象保存到page域中的名称。
begin属性:用于指定从集合中第几个元素开始进行迭代,begin的索引值从0开始,
如果没有指定items属性,就从begin指定的值开始迭代,直到迭代结束为止。
step属性:用于指定迭代的步长,即迭代因子的增量。
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<%String[] fruits = { "apple", "orange", "grape", "banana" };%>
String数组中的元素:
<c:forEach var="name" items="<%=fruits%>">
${name}<br />
</c:forEach>
<% Map userMap = new HashMap();
userMap.put("Tom", "123");
userMap.put("Make", "123");
userMap.put("Lina", "123"); %>
HashMap集合中的元素:
<c:forEach var="entry" items="<%=userMap%>">
${entry.key} ${entry.value}<br />
</c:forEach>
</body>
</html>
在部分情况下,需要指定<c:forEach>标签循环的次数、起始索引和结束索引,在JSTL的Core标签库中,<c:forEach>标签的begin、end和step属性分别用于指定循环的起始索引、结束索引和步长。使用这些属性可以迭代集合对象中某一范围内的元素。
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
colorsList集合(指定迭代范围和步长)<br />
<%
List colorsList=new ArrayList();
colorsList.add("red");
colorsList.add("yellow");
colorsList.add("blue");
colorsList.add("green");
colorsList.add("black");
%>
<c:forEach var="color" items="<%=colorsList%>" begin="1"
end="3" step="2">
${color}
</c:forEach>
</body>
</html>
<c:forEach>标签的varStatus属性用于设置一个javax.servlet.jsp.jstl.core.LoopTagStatus类型的变量,这个变量包含了从集合中取出元素的状态信息。使用<c:forEach>标签的varStatus属性可以获取以下信息:
count:表示元素在集合中的序号,从1开始计数;
index:表示当前元素在集合中的索引,从0开始计数;
first:表示当前是否为集合中的第一个元素;
last:表示当前是否为集合中的最后一个元素;
04. URL相关标签
<c:param>、<c:redirect>和<c:url>标签
在开发一个Web应用程序时,通常会在JSP页面中完成URL的重写以及重定向等特殊功能,为了完成这些功能,Core标
签库也提供了相应标签,这些标签包括<c:param>、<c:redirect>和<c:url>。其中<c:param>标签用于获取URL地址中的
附加参数,<c:url>标签用于按特定的规则重新构造URL,<c:redirect>标签负责重定向。
<c:param>标签通常嵌套在<c:url>标签内使用。<c:param>标签有两种语法格式,具体如下:
语法1:使用value属性指定参数的值
<c:param name="name" value="value">
语法2:在标签体中指定参数的值
<c:param name="name">
parameter value
</c:param>
上述语法格式中,可以看到<c:param>中有两个属性,下面对这两个属性分别进行讲解。
name属性用于指定参数的名称;
value属性用于指定参数的值,当使用<c:param>标签为一个URL地址附加参数时,它会自动对参数值进行URL编码,例
如,如果传递的参数值为“中国”,则将其转换为“%e4%b8%ad%e5%9b%bd”后再附加到URL地址后面,这也是使用<c:param>
标签的最大好处。
<c:url>标签的语法格式
<c:url>标签同样也有两语法格式,具体如下。
语法1:没有标签实体的情况
<c:url value="value" [context="context"] [var="varName"]
[scope="{page|request|session|application}"]>
语法2:有标签实体的情况,在标签体中指定构造URL参数
<c:url value="value" [context="context"] [var="varName"]
[scope="{page|request|session|application}"]>
<c:param>标签
</c:url>
<c:url>标签中有多个属性,下面对这些属性分别进行讲解。
value属性:用于指定构造的URL。
context属性:用于指定导入同一个服务器下其他Web应用的名称。
var属性:用于指定将构造的URL地址保存到域对象的属性名称。
scope属性:用于将构造好的URL保存到域对象中。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Title</title>
</head>
<body>
使用绝对路径构造URL:<br />
<c:url var="myURL"
value="http://localhost:8080/chapter04_war_exploded/cout.jsp">
<c:param name="username" value="张三" />
</c:url>
<a href="${myURL}">cout.jsp</a><br />
使用相对路径构造URL:<br />
<c:url var="myURL" value="cout.jsp?username=Tom" />
<a href="${myURL}">c_out.jsp</a>
</body>
</html>