JSP
的指令标签
使用包含操作,可以将一些重复的代码包含进来继续使用,从正常的页面组成来看,有时可能分为几 个区域。而其中的一些区域可能是一直不需要改变的,改变的就其中的一个具体内容区域。现在有两种方法可以实现上述功能。
方法一:在每个
JSP
页面(
HTML
)都包含工具栏、头部信息、尾部信息、具体内容
方法二:将工具栏、头部信息、尾部信息都分成各个独立的文件,使用的时候直接导入
很明显,第二种方法比第一种更好,第一种会存在很多重复的代码,并且修改很不方便,在
JSP
中如果要想实现包含的操作,有两种做法:静态包含
、
动态包含
,静态包含使用
include
指令即可,动态包含则需要使用 include
动作标签。
include
静态包含
静态包含就是将内容进行了直接的替换,就好比程序中定义的变量一样,是在
servlet
引擎转译时, 就把此文件内容包含了进去(两个文件的源代码整合到一起, 全部放到_jspService
方法中),所以只生成了一个 servlet
,所以两个页面不能有同名的变量。 运行效率高一点点。耦合性较高,不够灵活
include
动态包含
动态包含在代码的编译阶段,包含和被包含部分是两个独立的部分,只有当运行时,才会动态包含进来,好比方法的调用。
JSP
的四大域对象
四种属性范围
在
JSP
中提供了四种属性的保存范围,所谓的属性保存范围,指的就是一个设置的对象,可以再多少个
页面中保存并可以继续使用
1. page
范围
pageContext :
只在一个页面中保存属性,跳转之后无效
2. request
范围
request :
只在一次请求中保存,服务器跳转后依然有效
3. session
范围
session :
在一次会话范围中,无论何种跳转都可以使用
4. application
范围
application :
在整个服务器上保存

验证属性范围的特点
1. page
本页面取得,服务器端跳转()后无效
2. request
服务器跳转有效,客户端跳转无效
如果是客户端跳转,则相当于发出了两次请求,那么第一次的请求将不存在了;如果希望不管是客
户端还是服务器跳转,都能保存的话,就需要继续扩大范围。
3. session
无论客户端还是服务器端都可以取得,但是现在重新开启一个新的浏览器,则无法取得之前设置的
session
了,因为每一个
session
只保存在当前的浏览器当中,并在相关的页面取得。
对于服务器而言,每一个连接到它的客户端都是一个
session
如果想要让属性设置一次之后,不管是否是新的浏览器打开都能取得则可以使用
application
4. application
所有的
application
属性直接保存在服务器上,所有的用户
(
每一个
session)
都可以直接访问取得
只要是通过
application
设置的属性,则所有的
session
都可以取得,表示公共的内容,但是如果此
时服务器重启了,则无法取得了,因为关闭服务器后,所有的属性都消失了,所以需要重新设置。
问:使用哪个范围呢?
答:
在合理范围尽可能小
EL
表达式的使用
EL
表达式的语法
EL
(
Expression Language
) 是为了使
JSP
写起来更加简单。表达式语言的灵感来自于
ECMAScript
和
XPath
表达式语言,它提供了在
JSP
中简化表达式的方法,让
Jsp
的代码更加简化。
语法结构非常简单:
${expression}
EL
表达式一般操作的都是
域对象中的数据
,操作不了局部变量。
域对象的概念在
JSP
中一共有四个:
pageContext
,
request
,
session
,
application
;范围依次是,
本页面
,
一次请求
,
一次会话
,
整个应用程序
。
当需要指定从某个特定的域对象中查找数据时可以使用四个域对象对应的空间对象,分别是:
pageScope, requestScope, sessionScope, applicationScope
。
而
EL
默认的查找方式为从小到大查找,找到即可。当域对象全找完了还未找到则返回空字符串
""
。
EL
表达式的使用
获取数据
设置域对象中的数据
<%
pageContext
.
setAttribute
(
"uname"
,
"zhangsan"
);
// page
作用域
request
.
setAttribute
(
"uname"
,
"lisi"
);
// request
作用域
session
.
setAttribute
(
"uname"
,
"wangwu"
);
// session
作用域
application
.
setAttribute
(
"uname"
,
"zaholiu"
);
// application
%>
获取域对象的值
<%
--
获取域对象中的数据:默认查找方式为从小到大,找到即止。若四个范围都未找到,则返回空字符串。
- -
%>
${uname}
<!--
输出结果为:
zhangsan -->
获取指定域对象的值
${pageScope.uname}
<!-- page
作用域
-->
${requestScope.uname}
<!-- request
作用域
-->
${sessionScope.uname}
<!-- session
作用域
-->
${applicationScope.uname}
<!-- application
作用域
-->
获取
List
<%
List
<
String
>
list
=
new
ArrayList
<
String
>
();
list
.
add
(
"aaa"
);
list
.
add
(
"bbb"
);
list
.
add
(
"ccc"
);
request
.
setAttribute
(
"list"
,
list
);
%>
<%
--
获取
List
中指定下标的数据
$
{
list
[
下标
] }
获取集合的长度
$
{
list
.
size
()}
注:
list
代表的是存在域对象中的变量名(限域变量名)
--
%>
${list[1] }
<%
--
获取
List
中指定下标的数据
$
{
list
[
下标
] }
获取集合的长度
$
{
list
.
size
()}
注:
list
代表的是存在域对象中的变量名(限域变量名)
--
%>
${list[1] }
获取
Map
<%
Map map
=
new
HashMap
();
map
.
put
(
"aaa"
,
"111"
);
map
.
put
(
"bbb"
,
2222
);
map
.
put
(
"ccc-a"
,
333
);
request
.
setAttribute
(
"map"
,
map
);
%>
<%
--
获取
Map
中指定值
$
{
map
[
"key"
] }
或
$
{
map
.
key
}
注:
map
代表的是存在域对象中的变量名(限域变量名)
--
%>
${map.aaa }
${map["bbb"]}
获取
JavaBean
对象
empty
<%
--
empty
判断域对象是否为空。为空,返回
true
;不为空返回
false
;
$
{
empty
限域变量名
}
判断对象是否不为空。
$
{
!
empty
限域变量名
}
--
%>
${empty uname}
${empty list}
${empty map}
${empty user}
EL
运算
等值判断
比较两个值是否相等,返回
true
或
false
算术运算
大小比较
标签的使用
Java Server Pages Standard Tag Libray(JSTL)
:
JSP
标准标签库,是一个定制标签类库的集合,用于解决一些常见的问题,例如迭代一个映射或者集合、条件测试、XML
处理,甚至数据库和访问数据库操作等。
我们现在只讨论 JSTL
中最重要的标签,迭代集合以及格式化数字和日期几个标签。
核心标签库
:
包含
Web
应用的常见工作,比如:循环、表达式赋值、基本输入输出等。
格式化标签库
:
用来格式化显示数据的工作,比如:对不同区域的日期格式化等。
为了在
JSP
页面使用
JSTL
类库,必须以下列格式使用
taglib
指令:
<%
@taglib
uri
=
""
prefix
=
""
%>
//<%
@taglib
uri
=
"http://java.sun.com/jsp/jstl/core"
prefix
=
"c"
%>
前缀可以是任意内容,遵循规范可以使团队中由不同人员编写的代码更加相似;所以,建议使用事先设计好的前缀。
此时需要导入依赖
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
<version>
3.1.0
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.apache.taglibs
</groupId>
<artifactId>
taglibs-standard-impl
</artifactId>
<version>
1.2.5
</version>
</dependency>
<dependency>
<groupId>
javax.servlet.jsp.jstl
</groupId>
<artifactId>
jstl-api
</artifactId>
<version>
1.2
</version>
</dependency>
if
标签
if
标签先对某个条件进行测试,如果该条件运算结果为
true,
则处理它的主体内容,测试结果保存在一个 Boolean
对象中,并创建一个限域变量来引用
Boolean
对象。可以利用
var
属性设置限域变量名,利用 scope
属性来指定其作用范围。
语法格式
<c:if
test
=
"<boolean>"
var
=
"<string>"
scope
=
"<string>"
>
...
</c:if>
属性

示例
<%
request
.
setAttribute
(
"flag"
,
true
);
request
.
setAttribute
(
"num"
,
1
);
%>
<c:if
test
=
"${flag}"
>
<p>
结果为
true
<p>
</c:if>
<c:if
test
=
"${num > 0}"
>
<p>
num
的值比
0
大
<p>
</c:if>
注:
JSTL
中没有
else
标签
,为了模拟
else
的情景,需要使用两个
if
标签,并且这两个标签为
相反
的条件。
choose
、
when
和
otherwise
标签
choose
和
when
标签的作用与
Java
中的
switch
和
case
关键字相似,用于在众多选项中做出选择。 也就是说:他们为相互排斥的条件式执行提供相关内容。
switch
语句中有
case
,而
choose
标签中对应有
when
,
switch
语句中有
default
,而
choose
标签中有
otherwise
。
语法格式
<c:choose>
<c:when
test
=
"<boolean>"
>
...
</c:when>
<c:when
test
=
"<boolean>"
>
...
</c:when>
...
...
<c:otherwise>
...
</c:otherwise>
</c:choose>
属性
choose
标签没有属性。
when
标签只有一个
test
属性。
otherwise
标签没有属性。
示例
<%
request
.
setAttribute
(
"score"
,
90
);
%>
<c:choose>
<c:when
test
=
"${score < 60 }"
>
<h3>
你个小渣渣!
</h3>
</c:when>
<c:when
test
=
"${score >= 60 && score < 80 }"
>
<h3>
革命尚未成功,同志仍需努力!
</h3>
</c:when>
<c:otherwise>
<h3>
你很棒棒哦!
</h3>
</c:otherwise>
</c:choose>
注意点
choose
标签和
otherwise
标签没有属性,而
when
标签必须设置
test
属性
choose
标签中必须有至少一个
when
标签,可以没有
otherwise
标签
otherwise
标签必须放在最后一个
when
标签之后
choose
标签中只能有
when
标签和
otherwise
标签,
when
标签和
otherwise
标签可以嵌套其他标签
otherwise
标签在所有的
when
标签不执行的情况下才会执行
迭代标签
forEach
是将一个主体内容迭代多次,或者迭代一个对象集合。可以迭代的对象包括所有的
java.util.Collection
和
java.util.Map
接口的实现,以及对象或者基本类型的数组。他还可 以迭代
java.util.Iterator
和
java.util.Enumeration,
但不能在多个动作指令中使用
Iterator
或者
Enumeration,
因为
Iterator
或者
Enumeration
都不能重置(
reset
)。 各属性含义如下:
forEach
标签
语法格式
<c:forEach
items
=
"<object>"
begin
=
"<int>"
end
=
"<int>"
step
=
"<int>"
var
=
"<string>"
varStatus
=
"<string>"
>
</c:forEach>
属性

forEach varStatus
属性
index
:
当前这次迭代从
0
开始的迭代索引
count
:
当前这次迭代从
1
开始的迭代计数
first
:
用来表明当前这轮迭代是否为第一次迭代的标志
last
:
用来表明当前这轮迭代是否为最后一次迭代的标志
格式化动作标签
JSTL
提供了格式化和解析数字和日期的标签
,
我们讨论里面有:
formatNumber
、
formatDate
、
parseNumber
及
parseDate
。
formatNumber
标签
formatNumber
标签用于格式化数字,百分比,货币。该标签用指定的格式或精度来格式化数字。
(将数值型数据转换成指定格式的字符串类型。)
语法格式
<fmt:formatNumber
value="<string>"
type="<string>"
var="<string>"
scope="<string>"/>
属性

注意:
1.
如果设置了
var
属性,则格式化后的结果不会输出,需要通过
el
表达式获取
var
对应的限域变量名
2.
默认的类型(
type
)的取值为
number
。可取值:
number
数值型、
percent
百分比类型、
currency
货币型
formatDate
标签
formatDate
标签用于使用不同的方式格式化日期。(将
Date
型数据转换成指定格式的字符串类
型。)
语法格式
<fmt:formatDate
value
=
"<string>"
type
=
"<string>"
dateStyle
=
"<string>"
timeStyle
=
"<string>"
pattern
=
"<string>"
timeZone
=
"<string>"
var
=
"<string>"
scope
=
"<string>"
/>
属性

标签格式模式

示例
<%
request
.
setAttribute
(
"myDate"
,
new
Date
());
%>
${myDate }
<br/>
<fmt:formatDate
value
=
"${myDate }"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"date"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"time"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"both"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"both"
dateStyle
=
"full"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"both"
dateStyle
=
"long"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"both"
dateStyle
=
"short"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"both"
timeStyle
=
"full"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
type
=
"both"
timeStyle
=
"long"
/><br/>
<fmt:formatDate
value
=
"${myDate }"
pattern
=
"HH:mm yyyy/MM/dd"
/><br/>
parseNumber
标签
parseNumber
标签用来解析数字,百分数,货币。(
parseNumber
标签可以将数字、货币或百分比
类型的字符串转换成数值型。
parseDate
标签
parseDate
标签用于解析日期。(将指定格式的字符串转换成
Date
类型。)
语法格式
<fmt:parseDate
value="<string>"
type="<string>"
dateStyle="<string>"
timeStyle="<string>"
pattern="<string>"
var="<string>"
scope="<string>"/>
属性

示例
<fmt:parseDate
value
=
"2020-01-06"
type
=
"date"
/> <br>
<fmt:parseDate
value
=
"2020/01/06"
pattern
=
"yyyy/MM/dd"
/> <br>