JavaServer Pages标准标签库
Stephanie Bodoff
JavaServer Pages标准标签库(JSTL)封装了许多JSP应用程序共有的核心功能。例如,不需要用脚本或者众多不同厂商的不同迭代器标签对列表进行迭代,JSTL定义了在所有地方都可以使用的标准标签。这种标准化使您可以学习一种标签后,在多个JSP容器中使用它。而且,当标签标准化以后,容器可以优化对它们的实现。
JSTL支持通用的、结构化的任务,如迭代和条件、操作XML文档的标签、国际化标签以及以及用SQL访问数据库的标签。它还引入了表达式语言的概念以简化页面的开发。JSTL还提供了集成现有标签库与JSTL的框架。
本章通过在前面几章讨论的Duke's Bookstore应用程序的JSP版本的内容展示JSTL。假定您已经熟悉了第16章中的“使用标签”中的内容。
JSP页面示例
本章通过如下重新编写JSP版本的、在第16章讨论过的Duke's Bookstore应用程序的内容来展示JSTL:
· 用JSTL核心标签替换Struts逻辑标签。
· 用消息格式标签替换访问消息储存的scriptlet。
· 用通过JSTL SQL标签对数据库的直接调用替换JavaBean组件数据库helper。对于大多数应用程序来说,最好将对数据库的调用封装到bean中。JSTL包含SQL标签,在创建已有原型的应用程序并有可能减少创建bean的开销的情况下可以使用这个标签。
Duke's Bookstore应用程序的源代码在解开教程压缩包时创建的<JWSDP_HOME>/docs/tutorial/examples/web/bookstore4目录中(见运行示例)。
要编译、安装和运行这个例子:
1. 在终端窗口,进入 <JWSDP_HOME>/docs/tutorial/examples/web/bookstore4.
2. 运行ant build。Build目标会进行所有需要的编译并将文件拷贝到<JWSDP_HOME>/do
cs/tutorial/examples/web/bookstore4/build 目录中。
3. 确保已经启动Tomcat。
4. 运行ant install。install目标通知Tomcat新的内容已经可用。
5. 如果还没有做的话,启动PointBase数据库服务器并填入数据 (见从Web应用程序访问数据库)。
6. 打开书店URL localhost:8080/bookstore4/enter.
有关诊断常问题的帮助见常见问题及其解决方法和故障排除。
使用JSTL
JSTL包括很多种不同的标签,可应用到不同功能的领域中。因此,通过多个标签库描述符(TLD)明确表明它所覆盖的功能领域,并给每一领域它自己的命名空间。表17-1总结了这些功能领域,以及在本章和Duke's Bookstore应用程序中使用的逻辑TLD名和前缀。
表 17-1 JSTL 标签 | ||||
领域 | 功能 | 标签 | TLD | 前缀 |
核心 | 支持表达式语言 | catch out remove set | /jstl-c | c |
流程控制 | choose when otherwise forEach forTokens if | |||
URL管理 | import param redirect param url param | |||
XML | 核心 | out parse set | /jstl-x | x |
流程控制 | choose when otherwise forEach if | |||
转换 | transform param | |||
I18n | 区域 | setLocale | /jstl-fmt | fmt |
编排消息格式 | bundle message param setBundle | |||
编排数字和日期格式 | formatNumber formatDate parseDate parseNumber setTimeZone timeZone | |||
数据库 | setDataSource | /jstl-sql | sql | |
SQL | query dateParam param transaction update dateParam param | |||
例如,要在JSP页面中使用JSTL核心标签,用引用TLD的taglib指令声明库:
<%@ taglib uri="/jstl-core" prefix="c" %>
JSTL标签库有两种版本(见孪生库)。JSTL-EL库的TLD命名为prefix.tld。JSTL-RT库的TLD命名为prefix-rt.tld。由于在本章讨论的例子使用逻辑TLD名,所以我们用Web应用部署描述符中的taglib元素将逻辑名映射为实际TLD位置。下面是将核心库逻辑TLD名/jstl-c映射到其位置/WEB-INF/c.tld的项:
<taglib>
<taglib-uri>/jstl-c</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
<taglib-uri>/jstl-c</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
在Java WSDP中,JSTL TLD储存在<JWSDP_HOME>/jstl-1.0.3/tld中。在构建Duke's Bookstore应用程序时,这些TLD自动拷贝到<JWSDP_HOME>/docs/tutorial/examples/web/bookstore4/build/WEB-INF中。
还可以在taglib指令中用绝对URI引用TLD:
· 核心: java.sun/jstl/core
· XML: java.sun/jstl/xml
· 国际化: java.sun/jstl/fmt
· SQL: java.sun/jstl/sql
在使用绝对URI时,不必在l中添加taglib元素,JSP容器会自动定位在JSTL库实现中的TLD。
除了声明标签库,还需要使JSTL API及其实现对于Web应用程序是可用的。它们是以<JWSDP_HOME>/jstl-1.0.3中的jstl.jar和<JWSDP_HOME>/jstl-1.0.3/standard中的standard.jar文档形式发布的。在构建Duke's Bookstore应用程序时,这些库会自动拷贝到<JWSDP_HOME>/docs/tutorial/examples/web/bookstore4/build/WEB-INF/lib中。
表达式语言支持
jsp创建JSTL的一个重要功能就是对表达式语言(EL)的支持。表达式语言结合JSTL标签,使得访问应用程序数据和以简单方式操纵它变得容易了,不需要使用scriptlet或者请求时表达式。当前,页面编写者必须使用表达式<%= aName %>访问系统的值或者用户定义的JavaBean组件。如:
<x:aTag att="<%= Attribute("aName") %>">
对于嵌入式bean属性就更复杂了:
<%= Foo().getBar() %>
这使得页面的编写比它需要的更复杂。
表达式语言使页面编写者可以用简单的语法访问对象,如对于简单的变量
<x:atag att="${aName}">
或者对于嵌入的属性
<x:aTag att="${aName.foo.bar}">
JSTL表达式语言将JSP scoped 属性提升为业务逻辑与JSP页面交换信息的标准方式。例如,为这个条件标签的test属性提供一个比较名为cart的会话作用域属性中的项目数是否为0的表达式:
<c:if test="${sessionScope.cart.numberOfItems > 0}"> ... </c:if>
JSP规范的下一个版本将会对所有自定义标签库的表达式语言进行标准化。这一版本的JSTL包括这一表达式语言的一个快照。
孪生库
JSTL标签库有两个版本,它们只是在对属性值使用运行时表达式的方式上有所不同。
在JSTL-RT标签库,表达式是在页面的脚本语言中指定的。这正是当前标签库的工作方式。
在JSTL-EL标签库中,表达式是在JSTL表达式语言中指定的。表达式是以EL的语法所写的一个String文字。
在使用EL标签库时,不能为一个属性的值传递脚本语言表达式。这个规则使它可以在转换时验证表达式的语法。
JSTL 表达式语言
JSTL表达式语言负责处理表达式和文字。表达式由${ }字符所包围。例如:
<c:if test="${bean1.a < 3}" />
所有不以${开始的值都认为是文字,用所预期的类型的PropertyEditor将文字解析为预期类型:
<c:if test="true" />
包含字符的文字值必须进行如下转义:
<mytags:example attr1="an expression is ${'${'}true}" />
属性
可以通过名称访问属性,也可以加上作用域。属性的属性是用.操作符访问的,并可任意嵌套。
EL统一了对.和[ ]操作符的处理。因此,pr-b等于expr-a[expr-b]。要判断expr-a[expr-b],需将expr-a按value-a判断,将expr-b按value-b判断。
· 如果value-a是一个Map,返回(value-b)。
· 如果value-a是一个List或者数组,强制value-b为int并相应并返回(value-b)或者(value-a, value-b)。
· 如果value-a是JavaBean对象,强制value-b为String。如果value-b是value-a的可读属性,则返回getter调用的结果。
EL通过将标识作为属性查询、根据PageContext.findAttribute(String)的行为对标识进行判断。例如,${product}会查询名为product的属性,搜索页面、请求、会话和应用程序作用域,并返回其值。如果没有到属性,则返回null。注意与一个在下面一节中描述的隐式对象相匹配的标识会返回该隐式对象而不是属性值。
隐式对象
JSTL 表达式语言定义了一组隐式对象:
· pageContext: PageContext对象
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论