- 内容提要
- 作者简介
- 译者简介
- 前言
- HTTP
- Servlet 和 JSP
- 下载 Spring 或使用 STS 与 Maven/Gradle
- 手动下载 Spring
- 使用 STS 和 Maven/Gradle
- 下载 Spring 源码
- 本书内容简介
- 下载示例应用
- 第 1 章Spring 框架
- 第 2 章模型 2 和 MVC 模式
- 第 3 章Spring MVC 介绍
- 第 4 章基于注解的控制器
- 第 5 章数据绑定和表单标签库
- 第 6 章转换器和格式化
- 第 7 章验证器
- 第 8 章表达式语言
- 第 9 章JSTL
- 第 10 章国际化
- 第 11 章上传文件
- 第 12 章下载文件
- 第 13 章应用测试
- 附录 A Tomcat
- 附录 B Spring Tool Suite 和 Maven
- 附录 C Servlet
- 附录 D JavaServer Pages
- 附录 E 部署描述符
9.3 一般行为
下面介绍 Core 库中用来操作有界变量的 3 个一般行为:out、set 和 remove。
9.3.1 out 标签
在运算表达式时,out 标签是将结果输出到当前的 JspWriter。out 的语法有两种形式,即有 body content 和没有 body content。
< c:out value="value" [escapeXml="{true |false}"] [default="defaultValue"]/> < c:out value="value" [escapeXml="{true|false}"]> default value < /c:out>注意:
在标签的语法中,[]表示可选的属性。如果值带下划线,则表示为默认值。
out 的 body content 为 JSP。out 标签的属性见表 9.2。
表 9.2 out 标签的属性
属性 | 类型 | 描述 |
|---|---|---|
value*+ | 对象 | 要计算的表达式 |
escapeXml+ | 布尔 | 表示结果中的字符<、>、&、'和 "将被转换成相应的实体码,如<转换成 lt;等等。 |
default+ | 对象 | 默认值 |
例如,下列的 out 标签将输出有界变量 X 的值:
<c:out value="${x}"/>默认情况下,out 会将特殊字符<、>、'、"和&分别编写成它们相应的字符实体码 <、 >、'、"和&。
在 JSP 2.0 版本前,out 标签是用于输出有界对象值的最容易的方法。在 JSP 2.0 及其更高的版本中,除非需要对某个值进行 XML 转义,否则可以放心地使用 EL 表达式:
${x}警告:如果包含一个或多个特殊字符的字符串没有进行 XML 转义,它的值就无法在浏览器中正常显示。此外,没有转义的特殊字符,会使网站易于遭受交叉网站的脚本攻击。例如,别人可以对它 post 一个能够自动执行的 JavaScript 函数/表达式。
out 中的 default 属性可以赋一个默认值,当赋予其 value 属性的 EL 表达式返回 null 时,就会显示默认值。default 属性可以赋动态值,如果这个动态值返回 null,out 就会显示一个空的字符串。
例如,在下面的 out 标签中,如果在 HttpSession 中没有找到 myVar 变量,就会显示应用程序范围的变量 myVar 值。如果没有找到,则输出一个空的字符串。
<c:out value="${sessionScope.myVar}"
default="${applicationScope.myVar"/>9.3.2 url 标签
url 标签是非常有用的。简而言之,url 标签执行以下任一操作:
如果当前上下文路径为“/”(即应用程序部署为默认上下文),则它将空字符串附加到指定的路径。
如果当前上下文路径不是“/”,它会将上下文路径添加到指定的路径。
本节将通过以下一个小的应用程序来解释 url 标签的重要性,其结构在图 9.1 中给出。

图 9.1 demo 应用的目录结构
该应用程序由两个 JSP 页面 main.jsp 和 admin.jsp 组成。 main.jsp 文件位于应用程序根目录中,admin.jsp 文件位于 admin 文件夹中。二者都需要显示在图像文件夹中的两个图像,image1.png 和 image2.png。请注意,图像的绝对路径如下。
http://host/context/image/image1.png
http://host/context/image/image2.png因为两个图像从不同位置被引用多次,为了方便使用,用一个包含文件来引用它们。任何需要显示图像的 JSP 页面仅需要将该包含文件添加到文件中即可。include 文件夹表明了有 4 个 JSP 页面这么做了。
清单 9.1 展示了第一个包含文件 inc1.jspf 的内容。
清单 9.1 inc1.jsp 的内容
inc1.jsp
<img src="image/image1.png"/>
<img src="../image/image2.png"/第一个包含文件包含路径是相对于当前页的路径。假设 main.jsp 页面的 URL 是 http://host/context/main.jsp,那么这两个图像的 URL 将被解析为以下 URL:
http://host/context/image/image1.png
http://host/context/../image/image2.png不难想象,结果不太令人满意。第一个图像能正确显示,但第二个图像不能。
当通过 http://host/context/admin/admin.jsp 访问管理页面时,图像的 URL 解析如下:
http://host/context/admin/image/image1.png
http://host/context/admin/../image/image2.png结果,第一个图像将不显示,但第二个图像将显示。
很明显,使用相对路径并不总能工作,因为可以从不同目录中的 JSP 页面调用包含文件。我们唯一的希望是使图像 URL 相对于应用程序本身。所以就有了第二个包含文件:inc2.jspf(见清单 9.2)。
清单 9.2:inc2.jspf 的内容
inc2.jsp
<img src="/image/image1.png"/>
<img src="/image/image2.png"/>这看起来不错,应该能工作了,对吧?遗憾的是,它并不适用于所有情况。这是因为在开发应用程序时,部署上下文路径通常是未知的。根据应用程序是否部署为默认上下文,admin.jsp 页面可能具有以下 URL 之一:
http://localhost/jstl-demo/admin/admin.jsp
http://localhost/admin/admin.jsp在这两种情况下,浏览器不知道上下文路径。事实上,在第一个 URL 的情况下,它认为应用程序被部署为默认上下文,jstl-demo 是一个目录。因此,它将解析到第一个图像的 URL 为 http://localhost/image/image1.png,这使得图像无法显示。
仅当应用程序已部署到默认上下文时,才能正确显示这两个图像。然而,这足以说明 inc2.jspf 不是正确的解决方案。
url 标签是我们的救星。先看下使用了 url 标签的 inc3.jspf 的内容,见清单 9.3。
清单 9.3:inc3.jspf 的内容
< %@ taglib uri ="http://java.sun.com/jsp/jstl/core"prefix ="c"%>
inc3.jsp
< img src ="< c:url value ="/image/image1.png"/>"/>
< img src ="< c:url value ="/image/image2.png"/>"/>这解决了问题,因为 url 标签在服务器上执行,它知道上下文路径是什么。所以,它可以正确地解析图像的路径。
还可以使用 EL 表达式,如清单 9.4 中的 inc4.jspf 所示。
清单 9.4:inc4.jspf 的内容
inc4.jsp
<! - $ {cp = pageContext.request.contextPath} -->
<img src ="${cp =="/"?" ":cp}/image/image1.png"/>
<img src ="${cp =="/"?" ":cp}/image/image2.png"/>可以使用以下表达式获取上下文路径:
${pageContext.request.contextPath}相同的表达式将多次使用,所以我还创建了一个快捷方式 cp。
${cp = pageContext.request.contextPath}然而,该值仍然会发送到浏览器,这就是为什么它被放在一个 HTML 注释中。然后,你只需要测试上下文路径是“/”(默认上下文)还是别的东西。
${cp =="/"? "":cp}图 9.2 显示了非默认上下文中的 admin.jsp 页面。

图 9.2 图像引用的四种不同方式
正如你可以看到的,只有 inc3.jspf 和 inc4.jspf(分别采用 url 标签和 EL)能够工作。
9.3.3 set 标签
利用 set 标签,可以完成以下工作:
(1)创建一个字符串和一个引用该字符串的有界变量。
(2)创建一个引用现存有界对象的有界变量。
(3)设置有界对象的属性。
如果用 set 创建有界变量,那么,在该标签出现后的整个 JSP 页面中都可以使用该变量。
set 标签的语法有 4 种形式。第一种形式用于创建一个有界变量,并用 value 属性在其中定义一个要创建的字符串或者现存有界对象。
< c:set value="value" var="varName"
[scope="{page |request|session|application}"]/>这里的 scope 属性指定了有界变量的范围。
例如,下面的 set 标签创建了字符串“The wisest fool”,并将它赋给新创建的页面范围变量 foo:
<c:set var="foo" value="The wisest fool"/>下面的 set 标签则创建了一个名为 job 的有界变量,它引用 requestScope 对象 position。变量 job 的范围为 page。
<c:set var="job" value="${requestScope.position}" scope="page"/>注意:
最后一个例子可能有点令人费解,因为它创建了一个引用请求范围对象的页面范围变量。如果清楚有界对象本身并非真的在 HttpServletRequest“里面”,就不难明白了。引用(名为 position)其实是指引用该对象。有了上一个例子中的 set 标签,再创建一个引用相同对象的有界变量(job)即可。
第二种形式与第一种形式相似,只是要创建的字符串或者要引用的有界对象是作为 body content 赋值的。
< c:set var="varName" [scope="{page |request|session|application}"]> body content </c:set>第二种形式允许在 body content 中有 JSP 代码。
第三种形式是设置有界对象的属性值。target 属性定义有界对象以及有界对象的 property 属性。对该属性的赋值是通过 value 属性进行的。
< c:set target="target" property="propertyName" value="value"/>例如,下面的 set 标签是将字符串“Tokyo”赋予有界对象 address 的 city 属性。
<c:set target="${address}" property="city" value="Tokyo"/>注意,必须在 target 属性中用一个 EL 表达式来引用这个有界对象。
第四种形式与第三种形式相似,只是赋值是作为 body content 完成的。
< c:set target="target" property="propertyName">
body content
< /c:set>例如,下面的 set 标签是将字符串“Beijing”赋予有界对象 address 的 city 属性。
<c:set target="${address}" property="city">Beijing</c:set>set 标签的属性见表 9.3。
表 9.3 set 标签的属性
属性 | 类型 | 描述 |
|---|---|---|
value+ | 对象 | 要创建的字符串,或者要引用的有界对象,或者新的属性值 |
var | 字符串 | 要创建的有界变量 |
scope | 字符串 | 新创建的有界变量的范围 |
target+ | 对象 | 其属性要被赋新值的有界对象;这必须是一个 JavaBeans 实例或者 java.util.Map 对象 |
property+ | 字符串 | 要被赋新值的属性名称 |
9.3.4 remove 标签
remove 标签用于删除有界变量,其语法如下:
< c:remove var="varName"
[scope="{page |request|session|application}"]/>注意,有界变量引用的对象不能删除。因此,如果另一个有界对象也引用了同一个对象,仍然可以通过另一个有界变量访问该对象。
remove 标签的属性见表 9.4。
表 9.4 remove 标签的属性
属性 | 类型 | 描述 |
|---|---|---|
var | 字符串 | 要删除的有界变量的名称 |
scope | 字符串 | 要删除的有界变量的范围 |
举个例子,下面的 remove 标签删除了页面范围的变量 job。
<c:remove var="job" scope="page"/>绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论