本栏博客目录
Serlvet笔记一(Servlet基础)
Servlet笔记二(请求和响应)
Servlet笔记三(会话及其会话技术)
Servlet笔记四(JSP技术)
Servlet笔记五(EL表达式和JSTL)
Servlet笔记六(Servlet 高级)
Servlet笔记七(JDBC)
Servlet笔记八(数据库连接池与DBUtils工具)
Servlet笔记九(JSP 开发模型)
Servlet笔记十(文件上传和下载)
EL 表达式
在 JSP 开发中,为了获取 Servlet 对象中存储的数据,经常需要书写很多 Java 代码,这样得到做法会使 JSP 页面混乱,难以维护,为此,在 JSP 2.0 规范中提供了 EL 表达式。EL 是 Expression Language 的缩写,它是一种简单的数据访问语言。
初始 EL
由于 EL 可以简化 JSP 页面的书写,因此,在 JSP 的学习中,掌握 EL 是相当重要的。要使用 EL 表达式,首先要学习它的语法。EL 表达式的语法非常简单,都是以 “${” 开始,以"}" 结束的。
${ 表达式 }
需要注意的是,"${ 表达式 }" 中的表达式必须符合 EL 语法的要求。
使用 EL 表达式同样可以成功获取 Servlet 中存储的数据。同时,EL 表达式简化了 JSP 页面的书写。另外,当域对象里面的值不存在时,使用 EL 表达式获取域对象里面的值时返回空字符串;而使用 Java 方式获取,返回的值是 null 时,会报空指针异常。
EL 中的标识符
在 EL 表达式中,经常需要使用一些符号来标记一些名称,如变量名、自定义的函数名等,这些符号被称为标识符。EL 表达式中的标识符可以由任意的大小写字母、数字和下划线组成。为了避免出现非法的标识符,在定义标识符需要遵循以下规范。
- 不能以数字开头。
- 不能是 EL 中的保留字,如 and、or、gt。
- 不能是 EL 隐式对象,如:pageContext。
- 不能包含 单引号( ’ )、双引号( " )、减号( - ) 和 正斜杠( / ) 等特殊字符。
EL 中的保留字
保留字就是编程语言里面事先定义好并赋予了特殊含义的单词。和其他语言一样,EL 表达式中也定义了许多保留字,如 false、not 等。
and eq gt true instanceof
or ne le false empty
not lt ge null div mod
EL 中的变量
EL 表达式中的变量就是一个基本的存储单元,EL 表达式可以将变量映射到一个对象上,具体示例如下。
${product}
product 就是一个变量。EL 表达式中的变量不用事先定义就可以直接使用。表达式 ${product} 就可以访问变量 product 的值。
EL 中的常量
EL 表达式中的常量又称字面量,它是不能改变的数据。在 EL 表达式中包含多种常量。
1. 布尔常量
布尔常量用于区分一个事物的正反两面,它的值只有两个,分别是 true 和 false。
2. 整型常量
整型常量与 Java 中的十进制的整型常量相同,它的取值范围是 Java 语言中定义的常量 Long.MIN_VALUE 到 Long.MAX_VALUE 之间,即 ( − 2 ) 63 (-2)^{63} (−2)63 与 2 63 − 1 2^{63} - 1 263−1 之间的整数。
3. 浮点数常量
浮点数常量用整数部分加小数部分表示,也可以用指数形式表示,取值范围为 Java 中的 Double.MIN_VALUE 到 Double.MAX_VALUE 之间,即 4.9E-324 ~ 1.8E308 之间的浮点数。
4. 字符串常量
字符串常量是用单引号或双引号引起来的一连串字符。由于字符串常量需要用单引号或双引号引起来。字符串本身包含单引号、双引号、" \ " 都需要转义。
5. Null 常量
Null 常量用于表示变量引用的对象为空,它只有一个值,用 null 表示。
EL 中的运算符
EL 表达式支持简单的运算,例如,加(+)、减(-)、乘(*)、除(/)等。为此,在 EL 中提供了多种运算符,根据运算方式的不同,EL 中的运算符包括以下几种。
1. 点运算符(.)
EL 表达式中的点运算符,用于访问 JSP 页面中某些对象的属性,如 JavaBean 对象、List 集合、Array 数组等。
${customer.name}
访问 customer 对象中的 name 属性。
2. 方括号运算符([])
EL 表达式中的方括号运算符与点运算符的功能相同,都用于访问 JSP 页面中某些对象的属性。当获取的属性名中包含一些特殊符号,如 “-” 或 “?” 等并非字母或数字的符号,就只能使用方括号运算符来访问该属性。
${user["My-Name"]}
- 点运算符和方括号运算符在某种情况下可以互换,如
${student.name}
等价于${student["name"]}
。 - 方括号运算符还可以访问 List 集合或数组中指定索引的某个元素,如表达式
${users[0]}
用于访问集合或数组中的第 1 个元素。在这种情况下,只能使用方括号运算符,而不能使用点运算符。 - 方括号运算符和点运算符可以互相结合使用,例如,表达式
${users[0].userName}
可以访问集合或数组中的第 1 个元素的 userName 属性。
3. 算术运算符
EL 表达式中的算术运算符用于对整数和浮点数的值进行算术运算。使用这些算术运算符可以非常方便地在 JSP 页面进行算术运算,并且可以简化页面的代码量。
算术匀运算符
算术运算符 | 说明 | 算术表达式 | 结果 |
---|---|---|---|
+ | 加 | ${10+2} | 12 |
- | 减 | ${10-2} | 8 |
* | 乘 | ${10*2} | 20 |
/ (或 div) | 除 | ${10/4} 或 ${10 div 4} | 2.5 |
% (或 mod) | 取模(取余) | ${10%4} 或 ${10 mod 2} | 2 |
注意:"-" 运算符既可以作为减号,也可以作为负号;"/" 或 “div” 运算符在进行除法运算时,商为小数。
4. 比较运算符
EL 表达式中的比较运算符用于比较两个操作数的大小,操作数可以是各种常量、EL 变量或 EL 表达式,所有运算符执行的结果都是布尔类型。
比较运算符
比较运算符 | 说明 | 算术表达式 | 结果 |
---|---|---|---|
==(或 eq) | 等于 | ${10==2} 或 ${10 eq 2} | false |
!=(或 ne) | 不等于 | ${10!=2} 或 ${10 ne 2} | true |
<(或 lt) | 小于 | ${10<2} 或 ${10 lt 2} | false |
>(或 gt) | 大于 | ${10>2} 或 ${10 gt 2} | true |
<=(或 le) | 小于等于 | ${10<=2} 或 ${10 le 2} | false |
>=(或 ge) | 大于等于 | ${10>=2} 或 ${10 ge 2} | true |
为了避免与 JSP 页面的标签产生冲突,对于后 4 种比较运算符, EL 表达式中通常使用括号内的表示方式。例如,使用 “lt” 代替 “<” 运算符,如果运算符后面是数字,在运算符和数字之间至少要有一个空格,例如 ${1 lt 2};但后面如果有其他符号,则可以不加空格,例如 ${1lt(1+1)}
5. 逻辑运算符
EL 表达式中的逻辑运算符用于对结果为布尔类型的表达式进行运算,运算仍为布尔类型。
逻辑运算符
逻辑运算符 | 说明 | 算术表达式 | 结果 |
---|---|---|---|
&&(and) | 逻辑与 | ${true&&false} 或 ${true and false} | false |
||(or) | 逻辑或 | ${false||true} 或 ${false or true} | true |
!(not) | 逻辑非 | ${!true} 或 ${not true} | false |
6. empty 运算符
EL 表达式中的 empty 运算符用于判断某个对象是否为 null 或 “”,结果为布尔类型。
${empty var}
- var 变量不存在,即没有定义,例如表达式 ${empty name},如果不存在 name 变量,就返回 true;
- var 变量的值为 null,例如表达式${empty customer.name},如果 customer.name 的值为 null,就返回 true;
- var 变量引用集合 (Set、Map 和 List) 类型对象,并且在集合对象中不包含任何元素时,则返回值为 true。
7. 条件运算符
EL 表达式中条件运算符用于执行某种条件判断,它类似于 Java 语言中的 if-else 语句。
${A?B:C}
在上述语法格式中,表达式 A 的计算结果为布尔类型,如果表达式 A 的计算结果为 true,就执行表达式 B,并返回 B 的值;如果表达式 A 的计算结果为 false,就执行表达式 C,并返回 C 的值。
8. “()” 运算符
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 表达式取值时,没有数组的下标越界,没有空指针异常,没有字符串的拼接。
例子
servlet
@WebServlet("/mytest")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("name", "Harry");
req.setAttribute("pass", "123123");
Student stu = new Student();
stu.setName("XA");
stu.setAge(20);
req.setAttribute("stu", stu);
req.getRequestDispatcher("/myjsp.jsp").forward(req, resp);
}
}
class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
myjsp.jsp 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>myjsp</title>
</head>
<body>
${100 * 2 % 3}
<h2>欢迎访问</h2>
用户名:<%=request.getAttribute("name")%><br />
密码:<%=request.getAttribute("pass")%><br />
<hr>
使用EL表达式:<br />
用户名:${name}<br />
密码:${pass}<br />
<hr />
姓名:${stu.name}<br />
年龄:${stu.age}<br />
<hr />
empty:<br />
stu: ${empty stu}<br />
var: ${empty var}<br />
条件运算:<br />
1>2 ==> ${1>2?"yes":"no"}
</body>
</html>
页面效果:
EL 隐式对象
JSP 中,有隐式对象,在 EL 技术中,同样提供了隐式对象,EL 中的隐式对象共有 11 个。
EL 中的隐式对象
隐式对象名称 | 描述 |
---|---|
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 应用初始化信息的隐式对象。
1. pageContext 对象
为了获取 JSP 页面的隐式对象,可以使用 EL 表达式中的 pageContext 隐式对象。
${pageContext.response.characterEncoding}
上述实例中,pageContext 对象用于获取 response 对象中的 characterEncoding 属性。
pageContext 实例
jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="/mytest">点击访问</a>
<hr />
pageContext对象: <br/>
${pageContext.response.characterEncoding}<br />
请求URI: ${pageContext.request.requestURI}<br />
Content-Type响应头:${pageContext.response.contentType}<br />
服务器信息:${pageContext.servletContext.serverInfo}<br />
Servlet注册名:${pageContext.servletConfig.servletName}<br />
<hr />
<%-- ${requestScope.get("name")}--%>
<%-- ${pageScope.get("")}--%>
<%-- ${sessionScope.get("")}--%>
<%-- ${applicationScope.get("")}--%>
</body>
</html>
效果
2. Web 域相关对象
在 Web 开发中,pageContext、HttpServletRequest、HttpSession 和 ServletContext 这 4 个对象之所以可以存储数据,是因为它们内部都定义了一个 Map 集合,这些 Map 集合是有一定作用范围的,例如,HttpServletRequest 对象存储的数据只在当前请求中可以获取到。我们习惯把这些 Map 集合称为域,这些 Map 集合所在的对象称为 域对象。在 EL 表达式中,为了获取指定域中的数据,提供了 pageScope、requestScope、sessionScope 和 applicationScope 这 4 个隐式对象。
${pageScope.userName}
${requestScope.userName}
${sessionScope.userName}
${applicationScope.userName}
${userName} 就是在 page、request、session、application 这 4 个作用域内按顺序依次查找 userName 属性的。
scope 实例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>scope</title>
</head>
<body>
${pageContext.response.characterEncoding}
<hr />
<%
pageContext.setAttribute("username", "Jack");
request.setAttribute("bookname", "JavaWeb");
session.setAttribute("username", "Rose");
application.setAttribute("bookname", "SpringFramework");
%>
表达式\${pageScope.username}: ${pageScope.username}<br/>
表达式\${requestScope.username}: ${requestScope.bookname}<br/>
表达式\${sessionScope.username}: ${sessionScope.username}<br/>
表达式\${applicationScope.username}: ${applicationScope.bookname}<br/>
<hr />
${username}<br />
${bookname}<br />
</body>
</html>
效果
3. param 和 paramValues 对象
在 JSP 页面中,经常需要获取客户端传递的请求参数,为此,EL 表达式提供了 param 和 paramValues 两个隐式对象,这两个隐式对象专门用于获取客户端访问 JSP 页面式传递的请求参数。
param 对象用于获取请求参数的某个值,它是 Map 类型,与 request.getParameter() 方法相同,在使用 EL 获取参数时,如果参数不存在,返回的是空字符串,而不是 null。
${param.num}
如果一个请求参数中有多个值,可以使用 paramValues 对象来获取请求参数的所有值,该对象用于返回请求参数所有值组成的数组,如果要获取某个请求参数的第 1 个值:
${paramValues.nums[0]}
param 例子
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/index.jsp">
num1:<input type="text" name="num1" /><br />
num2:<input type="text" name="nums" /><br />
num3:<input type="text" name="nums" /><br />
num4:<input type="text" name="nums" /><br />
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</form>
<hr />
num1: ${param.num1}<br />
num2: ${paramValues.nums[0]}<br />
num3: ${paramValues.nums[1]}<br />
num4: ${paramValues.nums[2]}<br />
num5: ${paramValues.nums[3]}<br />
</body>
</html>
效果
4. Cookie 对象
在 JSP 开发中,经常需要获取客户端的 Cookie 信息,为此,在 EL 表达式中,提供了 Cookie 隐式对象,该对象是一个代表了所有 Cookie 信息的 Map 集合,Map 集合中元素的键为各个 Cookie 的名称,值则为对应的 Cookie 对象。
获取 cookie 对象的信息:${cookie.userName}
获取 cookie 对象的名称:${cookie.userName.name}
获取 cookie 对象的值:${cookie.userName.value}
cookie 例子
<%@ 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", "Jiaotong"));
%>
</body>
</html>
效果
header 例子
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>header.jsp</title>
</head>
<body>
user-agent = ${header["user-agent"]}<br />
accept-Language = ${headerValues["Accept-Language"][0]}<br />
</body>
</html>
效果
JSLT
在 JSP 1.1 规范开始,JSP 就支持使用自定义标签,使用自定义标签大大降低了 JSP 页面的复杂度,同时增加了代码的重用性。为此,许多 Web 应用厂商都定制了自身应用的标签库,然而同一功能的标签由不同的 Web 应用厂商制定可能是不同的,这就导致市面上出现了很多功能相同得到标签,令网页制作者无从选择。为了解决这个问题,Sun 公司制定了一套标准标签库(JavaServer Pages Standard Tag Library),简称 JSLT。
JSLT 虽然被称为标准标签库,而实际上这个标签库是由 5 个不同功能的标签库共同组成的。在 JSTL 1.1 规范中,为这 5 个标签库分别指定了不同的 URI 以及建议使用得到前缀。
JSTL 包含的标准库
标签库 | 标签库的 URI | 前缀 |
---|---|---|
Core | http://java.sun.com/jsp/jstl/core | c |
I18N | http://java.sun.com/jsp/jstl/fmt | fmt |
SQL | http://java.sun.com/jsp/jstl/sql | sql |
XML | http://java.sun.com/jsp/jstl/xml | x |
Functions | http://java.sun.com/jsp/jstl/functions | fn |
- Core 是一个核心标签库,它包含了实现 Web 应用中通用操作的标签。例如,用于输出文本内容的 <c:out> 标签、用于条件判断的 <c:if> 标签、用于迭代循环的 <c:forEach> 标签。
- I18N 是一个国际化/格式化标签库,它包含实现 Web 应用程序的国际化标签和格式化标签。例如,设置 JSP 页面的本地信息、设置 JSP 页面的时区、使日期按照本地格式显示等。
- SQL 是一个数据库标签库,它包含了用于访问数据库和对数据库中的数据进行操作的标签。例如,从数据库中获得数据库连接、从数据库表中检索数据等。由于在软件分层开发模型中,JSP 页面仅作为表示层,一般不会在 JSP 页面中直接操作数据库,因此,JSTL 中提供的这套标准库不经常使用。
- XML 是一个操作 XML 文档的标签库,它包含了对 XML 文档中的数据进行操作的标签。例如,解析 XML 文件、输出 XML 文档中的内容,以及迭代处理 XML 文档中的元素。XML 广泛应用于 Web 开发,使用 XML 标准库处理 XML 文档更加简单方便。
- Functions 是一个函数标签库,它提供了一套自定义 EL 函数,包含了 JSP 网页制作者经常要用到的字符串操作。例如,提取字符串中的子字符串、获取字符串的长度等。
下载 1.1.2 版本的,然后解压缩后,将 lib 下面的两个 JAR 包(jstl.jar 和 standard.jar),拷贝到对应项目模块的 web/WEB-INFO/lib 中,然后
Add as Library
注意:在使用时如果出现 ClassNotFound… 错误信息,需要把上面两个 jar 包拷也到 tomcat 的 lib 文件夹下。
测试 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" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>JSTL</title>
</head>
<body>
<c:out value="Hello World!"></c:out>
</body>
</html>
测试结果
JSTL 中的 Core 标签库
1. <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>
在上述语法格式中,没有标签体的情况,需要使用 default 属性指定默认值;有标签体的情况,在标签体中指定输出的默认值。可以看到 <c:out> 标签有多个属性,接下针对这些属性进行讲解。
- value 属性用于指定输出的文本内容。
- default 属性用于指定当 value 属性为 null 时所输出的默认值,该属性是可选的(方括号中的属性都是可选的)
- escapeXml 属性用于指定是否将 >、<、&、’、" 等特殊字符进行 HTML 编码转换后再进行输出,默认值为 true。
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>JSTL</title>
</head>
<body>
<c:out value="Hello World!"></c:out><br />
username属性的值为:<c:out value="${username}">Hello Jiaotong</c:out><br />
username属性的值为:<c:out value="${username}" default="Hello Jiaotong2" /><br />
excapeXml="true" ==> <c:out value="<h1>Hello World</h1>" escapeXml="true">unknow</c:out><br />
excapeXml="false" ==> <c:out value="<h1>Hello World</h1>" escapeXml="false">unknow</c:out><br />
</body>
</html>
2. <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>
- test 属性用于设置逻辑表达式。
- var 属性用于指定逻辑表达式中变量的名字。
- scope 属性用于指定 var 变量的作用范围,默认值为 page。如果属性 test 的计算结果为 true,那么标签体将被执行,否则标签体不会被执行。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>c_if</title>
</head>
<body>
<%
request.setAttribute("username", "Harry");
%>
<c:set value="10" var="visitCount" />
<c:if test="${visitCount==10}">
Hello,this is my first time to mysite
</c:if>
<hr />
<c:if test="${username=='Harry'}" var="username">
Hello, Harry, welcome to mysite
</c:if>
</body>
</html>
3. <c:choose> 标签
在程序开发中不仅需要使用 if 条件语句,还经常会使用 if-else 语句。为了在 JSP 页面中也可以完成同样的功能,Core 标签库提供了 <c:choose> 标签,该标签用于指定多个条件选择的组合边界,他必须与 <c:when>、<c:otherwise> 标签一起使用。
<c:choose> 标签没有属性,在它的标签体中只能嵌套一个或多个 <c:when> 标签和零个或一个 <c:otherwise> 标签,并且同一个 <c:choose> 标签中所有的 <c:when> 子标签必须出现在 <c:otherwise> 子标签之前。
<c:choose>
Body content(<when> and <otherwise> subtags)
</c:choose>
<c:when> 标签只有一个 test 属性,该属性的值为布尔类型。test 属性支持动态值,其值可以是一个条件表达式,如果条件表达式的值为 true,就执行这个 <c:when> 标签体的内容。
<c:when test="testCondition">
Body content
</c:when>
<c:otherwise> 标签没有属性,它必须作为 <c:choose> 标签最后分支出现。当所有的 <c:when> 标签的 test 条件都不成立时,才执行和输出 <c:otherwise> 标签体的内容。
<c:otherwise>
condtional block
</c:otherwise>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title></title>
</head>
<body>
<c:choose>
<c:when test="${empty param.username}">
unKnow user.
</c:when>
<c:when test="${param.username=='Jack'}">
Hi, Boss..
</c:when>
<c:when test="${param.username=='Tom'}">
Harry up Tom, there are so many work for you.
</c:when>
<c:otherwise>
You are not the stuff of my company.
</c:otherwise>
</c:choose>
</body>
</html>
4. <c:forEach> 标签
在 JSP 页面中,经常需要对集合对象进行循环迭代操作,为此,Core 标签库提供了一个 <c:forEach> 标签,该标签专门用于迭代集合对象中的元素,如:Set、List、Map、数组等,并且能重复执行标签体中的内容,它有两种语法格式:
语法 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>
- var 属性用于指定将当前迭代到的元素保存到 page 域中的名称。
- items 属性用于指定将要迭代的集合对象。
- varStatus 属性用于指定当前迭代状态信息的对象保存到 page 域中的名称。
- begin 属性用于指定从集合中第几个元素开始进行迭代,begin 的索引值从 0 开始。如果没有指定 items 属性,就从 begin 指定的值开始迭代,直到迭代结束为止。
- step 属性用于指定迭代的步长,即迭代因子的增量。
<c:forEach> 标签的 varStatus 属性用于设置一个 javax.servlet.jsp.jstl.core.LoopTagStatus 类型的变量,这个变量包含了从集合中取出元素的状态信息,使用 <c:forEach> 标签的 varStatus 属性可以获取以下信息。
- count:表示元素在集合中的序号,从 1 开始计数。
- index:表示当前元素在集合中的索引,从 0 开始计数。
- first:表示当前是否为集合中的第 1 个元素。
- last:表示当前是否为集合中的最后一个元素。
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title></title>
</head>
<body>
<%
String fruits[] = {"apple", "orange", "grape", "banana"};
// request.setAttribute("fruits", fruits);
%>
<c:forEach var="name" items="<%=fruits%>" varStatus="now">
<%-- <c:forEach var="name" items="${fruits}" varStatus="now">--%>
${name}<br />
</c:forEach>
<hr />
<%
Map userMap = new HashMap();
userMap.put("Tom", "111");
userMap.put("Jack", "222");
userMap.put("Harry", "123");
userMap.put("Rose", "321");
%>
<c:forEach var="uname" items="<%=userMap%>">
${uname}<br/>
${uname.key} --> ${uname.value} <br/>
</c:forEach>
</body>
</html>
Book.java
public class Book {
private String name;
private String author;
private Double price;
public Book(){
}
public Book(String name, String author, Double price) {
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
MyServlet.java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/mytest")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
List<Book> books = new ArrayList<>();
Book b1 = new Book("Java", "xiaowang", 19.9);
Book b2 = new Book("Html", "dali", 30.0);
Book b3 = new Book("python", "mei", 22.9);
books.add(b1);
books.add(b2);
books.add(b3);
req.setAttribute("books", books);
req.getRequestDispatcher("/bookinfo.jsp").forward(req, resp);
}
}
bookinfo.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title></title>
</head>
<body>
<h2>reading book</h2>
<table border="1">
<thead>
<tr><th>序号</th><th>书名</th><th>作者</th><th>价格</th></tr>
</thead>
<tbody>
<c:forEach var="book" items="${books}" varStatus="stat">
<tr>
<td>${stat.index+1}/${stat.count}</td>
<td>${book.name}</td>
<td>${book.author}</td>
<td>${book.price}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
5. <c:param> 标签和 <c:url> 标签
在开发一个 Web 应用程序时,通常会在 JSP 页面中完成 URL 的重写以及重定向等特殊功能,为了完成这些功能,在 Core 标签中,也提供了相应功能的标签,这些标签包括 <c:param>、<c:redirect>、<c:url>。其中,<c:param> 标签用于获取 URL 地址中的附加参数,<c:url> 标签用于按特定的规则重新构造 URL,<c:redirect> 标签负责重定向。
<c:param> 标签用于在 URL 地址中附加参数,它通常嵌套在 <c:url> 标签内使用。<c:param> 标签有两种语法格式:
语法 1:使用 value 属性指定参数的值
<c:param name="name" value="value">
语法 2:在标签体中指定参数的值
<c:param name="name">
parameter value
</c:param>
- name 属性用于指定参数的名称
- value 属性用于指定参数的值,当使用 <c:param> 标签为一个 URL 地址附加参数时,它会自动对参数进行 URL 编码。例如,如果参数传递的为 “中国”,则将其转换为 “%e4%b8%ad%e5%9b%bd” 后再附加到 URL 地址后面,这也是使用 <c:param> 标签最大好处。
在访问一个 JSP 页面时,通常会在 URL 中传递一些参数信息。为了方便完成这种功能,Core 标签库提供了一个 <c:url> 标签,该标签可以在 JSP 页面中构造一个新的地址,实现 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>
- value 属性用于指定构造的 URL。
- context 属性用于指定导入同一个服务器下其他 Web 应用的名称。
- var 属性用于指定将构造的 URL 地址保存到域对象中。
- scope 属性用于指定将构造好的 URL 保存到域对象中。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title></title>
</head>
<body>
使用绝对路径构造url:<br />
<c:url var="myurl" value="http://localhost:8080/register.jsp">
<c:param name="uname" value="Harry" />
<c:param name="country" value="uk"/>
</c:url>
<a href="${myurl}">register.jsp</a><br/>
<hr />
相对路径构造url:<br />
<c:url var="myurl" value="register.jsp?username=Jack&country=France" />
<a href="${myurl}">register.jsp</a><br/>
</body>
</html>