JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。在 developerWorks 上其新系列的第一篇文章中,软件工程师 Mark Kolb 向您展示了如何使用 JSTL 标记来避免在 JSP 页面中使用脚本编制元素。您还将了解如何通过从表示层删除源代码来简化软件维护。最后,您将了解 JSTL 经过简化的表达式语言,它允许在不必使用功能齐全的编程语言的情况下对 JSTL 操作指定动态属性值。
JavaServer Pages(JSP)是用于 J2EE 平台的标准表示层技术。JSP 技术提供了用于执行计算(这些计算用来动态地生成页面内容)的脚本编制元素和操作。脚本编制元素允许在 JSP 页面中包括程序源代码,在为响应用户请求而呈现页面时可以执行这些源代码。操作将计算操作封装到很象 HTML 或 XML 标记的标记中,JSP 页面的模板文本通常包含这些标记。JSP 规范只将几种操作定义成了标准,但从 JSP 1.1 开始,开发人员已经能够以定制标记库的方式创建其自己的操作了。
JSP 标准标记库(JSTL)是 JSP 1.2 定制标记库集,这些标记库实现大量服务器端 Java 应用程序常用的基本功能。通过为典型表示层任务(如数据格式化和迭代或条件内容)提供标准实现,JSTL 使 JSP 作者可以专注于特定于应用程序的开发需求,而不是为这些通用操作“另起炉灶”。
当然,您可以使用 JSP 脚本编制元素(scriptlet、表达式和声明)来实现此类任务。例如,可以使用三个 scriptlet 实现条件内容,清单 1 中着重显示了这三个 scriptlet。但是,因为脚本编制元素依赖于在页面中嵌入程序源代码(通常是 Java 代码),所以对于使用这些脚本编制元素的 JSP 页面,其软件维护任务的复杂度大大增加了。例如,清单 1 中的 scriptlet 示例严格地依赖于花括号的正确匹配。如果不经意间引入了一个语法错误,则条件内容中的嵌套其它 scriptlet 可能会造成严重破坏,并且在 JSP 容器编译该页面时,要使所产生的错误信息有意义可能会很困难。
清单 1. 通过 scriptlet 实现条件内容 <% if (user.getRole() == "member")) { %>
<p>Welcome, member!</p>
<% } else { %>
<p>Welcome, guest!</p>
<% } %>
修正此类问题通常需要相当丰富的编程经验。尽管通常会由十分精通页面布局和图形设计的设计人员来开发和维护 JSP,但是同一页面中的脚本编制元素出现问题时,需要程序员的介入。这种状况将单个文件中代码的责任分担给多人,因而使得开发、调试和增强此类 JSP 页面成为很麻烦的任务。通过将常用功能包装到定制标记库的标准集合中,JSTL 使 JSP 作者可以减少对编制脚本元素的需求,甚至可以不需要它们,并避免了相关的维护成本。
JSTL 1.0
JSTL 1.0 发布于 2002 年 6 月,由四个定制标记库(core、format、xml 和 sql)和一对通用标记库验证器(ScriptFreeTLV 和 PermittedTaglibsTLV)组成。core 标记库提供了定制操作,通过限制了作用域的变量管理数据,以及执行页面内容的迭代和条件操作。它还提供了用来生成和操作 URL 的标记。顾名思义,format 标记库定义了用来格式化数据(尤其是数字和日期)的操作。它还支持使用本地化资源束进行 JSP 页面的国际化。xml 库包含一些标记,这些标记用来操作通过 XML 表示的数据,而 sql 库定义了用来查询关系数据库的操作。
两个 JSTL 标记库验证器允许开发人员在其 JSP 应用程序中强制使用编码标准。可以配置 ScriptFreeTLV 验证器以在 JSP 页面中禁用各种类型的 JSP 脚本元素 ― scriptlet、表达式和声明。类似地,PermittedTaglibsTLV 验证器可以用来限制可能由应用程序的 JSP 页面访问的定制标记库集(包括 JSTL 标记库)。
尽管 JSTL 最终将会成为 J2EE 平台的必需组件,但目前只有少数应用程序服务器包括它。JSTL 1.0 的参考实现可作为 Apache 软件基金会(Apache Software Foundation)的 Jakarta Taglibs 项目(请参阅参考资料)的一部分而获得。可以将该参考实现中的定制标记库合并到任何支持 JSP 1.2 和 Servlet 2.3 规范的服务器,以添加对 JSTL 的支持。
表达式语言
在 JSP 1.2 中,可以使用静态字符串或表达式(如果允许的话)指定 JSP 操作的属性。例如,在清单 2 中,对 <jsp:setProperty> 操作的 name 和 property 属性指定了静态值,而用表达式指定了其 value 属性。这个操作的效果是将请求参数的当前值赋予命名的 bean 特性。以这种形式使用的表达式被称为请求时属性值(request-time attribute value),这是构建到 JSP 规范中的用于动态指定属性值的唯一机制。
清单 2. 合并请求时属性值的 JSP 操作
<jsp:setProperty name="user" property="timezonePref"
value='<%= request.getParameter("timezone") %>'/>
因为请求时属性值是用表达式指定的,所以它们往往有和其它脚本元素一样的软件维护问题。因此,JSTL 定制标记支持另一种用于指定动态属性值的机制。可以用简化的表达式语言(EL)而不使用完整的 JSP 表达式来指定 JSTL 操作的属性值。EL 提供了一些标识符、存取器和运算符,用来检索和操作驻留在 JSP 容器中的数据。EL 在某种程度上以 EcmaScript(请参阅参考资料)和 XML 路径语言(XML Path Language,XPath)为基础,因此页面设计人员和程序员都应该熟悉它的语法。EL 擅长寻找对象及其特性,然后对它们执行简单操作;它不是编程语言,甚至不是脚本编制语言。但是,与 JSTL 标记一起使用时,它就能使用简单而又方便的符号来表示复杂的行为。EL 表达式的格式是这样的:用美元符号({ })中,如清单 3 所示。
清单 3. 说明 EL 表达式定界符的 JSTL 操作
<c:out value="${ user.firstName}"/>
此外,您可以将多个表达式与静态文本组合在一起以通过字符串并置来构造动态属性值,如清单 4 所示。单独的表达式由标识符、存取器、文字和运算符组成。标识符用来引用存储在数据中心中的数据对象。EL 有 11 个保留标识符,对应于 11 个 EL 隐式对象。假定所有其它标识符都引用限制了作用域的变量。存取器用来检索对象的特性或集合的元素。文字表示固定的值 ― 数字、字符、字符串、布尔型或空值。运算符允许对数据和文字进行组合以及比较。
清单 4. 组合静态文本和多个 EL 表达式以指定动态属性值
<c:out value="Hello ${ user.firstName} ${ user.lastName}"/>
限制了作用域的变量
JSP API 通过 <jsp:useBean> 操作允许从 JSP 容器内的四个不同作用域中存储和检索数据。JSTL 通过提供用于指定和除去这些作用域中的对象的附加操作来扩展这一能力。此外,EL 提供将这些对象作为限制了作用域的变量进行检索的内置支持。特别地,任何出现在 EL 表达式中但不对应于任何 EL 隐式对象的标识符,都被自动假定为引用存储在四个 JSP 作用域的其中某个中的对象,这四个作用域是:
・页面作用域
・请求作用域
・会话作用域
・应用程序作用域
您可能还记得,只有在为特定请求处理页面期间才能检索存储在该页面作用域中的对象。如果对象是存储在请求作用域中的,可以在处理所有参与处理某请求的页面期间检索这些对象(譬如在对某个请求的处理中遇到了一个或多个 <jsp:include> 或 <jsp:forward> 操作)。如果对象是存储在会话作用域中的,则在与 Web 应用程序的交互式会话期间,可以由用户访问的任何页面检索它(即,直到与该用户交互相关联的 HttpSession 对象无效为止)。可以由任何用户从任何页面访问存储在应用程序作用域中的对象,直到卸载 Web 应用程序本身为止(通常是由于关闭 JSP 容器所致)。
通过将字符串映射为期望作用域中的对象来将对象存储到该作用域。然后,就可以通过提供相同字符串来从该作用域检索该对象。在作用域的映射中查找字符串,并返回被映射的对象。在 Servlet API 中,将此类对象称为相应作用域的属性。但是,在 EL 的上下文中,也将与属性相关联的字符串看作变量的名称,该变量通过属性映射的方式获得特定的值。
在 EL 中,与隐式对象无关联的标识符被认为是存储在四个 JSP 作用域中的名称对象。首先对页面作用域检查是否存在这样的标识符,其次对请求作用域、然后对会话作用域、最后对应用程序作用域依次进行这样的检查,然后测试该标识符的名称是否与存储在该作用域中的某个对象的名称匹配。第一个这样的匹配作为 EL 标识符的值被返回。通过这种方法,可以将 EL 标识符看作引用限制了作用域的变量。
从更技术的方面来说,没有映射到隐式对象的标识符是用 PageContext 实例的 findAttribute() 方法求值的,该实例表示对页面的处理,在该页面上,当前正在处理用于请求的表达式。标识符的名称作为参数传递给这个方法,然后该方法依次在四个作用域中搜索具有相同名称的属性。并将所找到的第一个匹配项作为 findAttribute() 方法的值返回。如果未在这四个作用域中找到这样的属性,则返回 null。
最终,限制了作用域的变量是四个 JSP 作用域的属性,这些属性具有可以用作 EL 标识符的名称。只要对限制了作用域的变量赋予由字母数字组成的名称,就可以通过 JSP 中提供的用于设置属性的任何机制来创建它们。这包括内置的 <jsp:useBean> 操作,以及由 Servlet API 中的几个类定义的 setAttribute() 方法。此外,四个 JSTL 库中定义的许多定制标记本身就能够设置作为限制了作用域的变量使用的属性值。
隐式对象
表 1 中列出了 11 个 EL 隐式对象的标识符。不要将这些对象与 JSP 隐式对象(一共只有九个)混淆,其中只有一个对象是它们所共有的。
表 1. EL 隐式对象
类别 标识符 描述
JSP pageContext PageContext 实例对应于当前页面的处理
作用域 pageScope 与页面作用域属性的名称和值相关联的 Map 类
requestScope 与请求作用域属性的名称和值相关联的 Map 类
sessionScope 与会话作用域属性的名称和值相关联的 Map 类
applicationScope 与应用程序作用域属性的名称和值相关联的 Map 类
请求参数 param 按名称存储请求参数的主要值的 Map 类
paramValues 将请求参数的所有值作为 String 数组存储的 Map 类
请求头 header 按名称存储请求头主要值的 Map 类
headerValues 将请求头的所有值作为 String 数组存储的 Map 类
Cookie cookie 按名称存储请求附带的 cookie 的 Map 类
初始化参数 initParam 按名称存储 Web 应用程序上下文初始化参数的 Map 类
尽管 JSP 和 EL 隐式对象中只有一个公共对象(pageContext),但通过 EL 也可以访问其它 JSP 隐式对象。原因是 pageContext 拥有访问所有其它八个 JSP 隐式对象的特性。实际上,这是将它包括在 EL 隐式对象中的主要理由。
其余所有 EL 隐式对象都是映射,可以用来查找对应于名称的对象。前四个映射表示先前讨论的各种属性作用域。可以用它们来查找特定作用域中的标识符,而不用依赖于 EL 在缺省情况下使用的顺序查找过程。
接下来的四个映射用来获取请求参数和请求头的值。因为 HTTP 协议允许请求参数和请求头具有多个值,所以它们各有一对映射。每对中的第一个映射返回请求参数或头的主要值,通常是恰巧在实际请求中首先指定的那个值。每对中第二个映射允许检索参数或头的所有值。这些映射中的键是参数或头的名称,但这些值是 String 对象的数组,其中的每个元素都是单一参数值或头值。
cookie 隐式对象提供了对由请求设置的 cookie 名称的访问。这个对象将所有与请求相关联的 cookie 名称映射到表示那些 cookie 特性的 Cookie 对象。
最后一个 EL 隐式对象 initParam 是一个映射,它储存与 Web 应用程序相关联的所有上下文的初始化参数的名称和值。初始化参数是通过 web.xml 部署描述符文件指定的,该文件位于应用程序的 WEB-INF 目录中。
存取器
因为 EL 标识符是作为隐式对象或限制了作用域的变量(通过属性来实现)解析的,因此有必要将它们转换成 Java 对象。EL 可以自动包装和解包其相应的 Java 类中的基本类型(例如,可以在后台将 int 强制转换成 Integer 类,反之亦可),但大多数的标识符将成为指向完整的 Java 对象的指针。
结果是,对这些对象的特性或(在对象是数组和集合的情况下)对其元素的访问通常是令人满意的。就为了实现这种用途,EL 提供了两种不同的存取器(点运算符(.)和方括号运算符([])),也支持通过 EL 操作特性和元素。
点运算符通常用于访问对象的特性。例如,在表达式 ${ user.firstName} 中,使用点运算符来访问 user 标识符所引用对象的名为 firstName 的特性。EL 使用 Java bean 约定访问对象特性,因此必须定义这个特性的 getter 方法(通常是名为 getFirstName() 的方法),以便表达式正确求值。当被访问的特性本身是对象时,可以递归地应用点运算符。例如,如果我们虚构的 user 对象有一个实现为 Java 对象的 address 特性,那么也可以用点运算符来访问这个对象的特性。例如,表达式 ${ user.address.city} 将会返回这个地址对象嵌套的 city 特性。
方括号运算符用来检索数组和集合的元素。在数组和有序集合(也即,实现了 java.util.List 接口的集合)的情况下,把要检索的元素的下标放在方括号中。例如,表达式 ${ urls[3]} 返回 urls 标识符所引用的数组或集合的第四个元素(和 Java 语言以及 Javascript 中一样,EL 中的下标是从零开始的)。
对于实现 java.util.Map 接口的集合,方括号运算符使用关联的键查找存储在映射中的值。在方括号中指定键,并将相应的值作为表达式的值返回。例如,表达式 ${ commands["dir"]} 返回与 commands 标识符所引用的 Map 中的 "dir" 键相关联的值。
对于上述两种情况,都可允许表达式出现在方括号中。对嵌套表达式求值的结果将被作为下标或键,用来检索集合或数组的适当元素。和点运算符一样,方括号运算符也可以递归应用。这使得 EL 能够从多维数组、嵌套集合或两者的任意组合中检索元素。此外,点运算符和方括号运算符还可以互操作。例如,如果数组的元素本身是对象,则可以使用方括号运算符来检索该数组的元素,并结合点运算符来检索该元素的一个特性(例如 ${ urls[3].protocol})。
假定 EL 充当指定动态属性值的简化语言,EL 存取器有一个有趣的功能(与 Java 语言的存取器不同),那就是它们在应用于 null 时不抛出异常。如果应用 EL 存取器的对象(例如,${ foo.bar} 和 ${ foo["bar"]} 中的 foo 标识符)是 null,那么应用存取器的结果也是 null。事实证明,在大多数情况下,这是一个相当有用的行为,不久您就会了解这一点。
最后,点运算符和方括号运算符可能实现某种程度的互换。
分享到:
相关推荐
### JSTL 入门:表达式语言 #### 引言 JSTL(JavaServer Pages Standard Tag Library,即JavaServer Pages标准标记库)是一种专为简化JavaServer Pages(JSP)应用程序开发与维护而设计的技术。JSTL提供了一系列预...
JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能...最后,您将了解 JSTL 经过简化的表达式语言,它允许在不必使用功能齐全的编程语言的情况下对 JSTL 操作指定动态属性值。
JSP 标准标记库(JSP Standard Tag Library,JSTL)是一个实现 Web 应用程序中常见的通用功能...最后,您将了解 JSTL 经过简化的表达式语言,它允许在不必使用功能齐全的编程语言的情况下对 JSTL 操作指定动态属性值。
JSTL提供的函数库可以增强JSP表达式语言的能力。例如,`fn:length()` 可以计算数组或集合的长度。 ```jsp ${fn:length(list)} ``` ### 六、JSTL I18N支持 JSTL提供了处理国际化和本地化的标签,如`fmt:message`...
JSTL的一个关键优点是它鼓励使用表达式语言(Expression Language,EL)而不是脚本元素。EL是一种简洁的语法,可以方便地访问JavaBean属性、JSP作用域中的变量以及执行基本的算术和逻辑运算。通过使用EL,JSP页面...
#### JSTL的表达式语言:简化动态属性设置 JSTL引入了一种简化版的表达式语言,允许开发者在不使用完整编程语言的情况下指定动态属性值。这极大地减少了在JSP页面中嵌入Java代码的需求,提升了代码的整洁度与维护性...
在"jstl入门示例源码"中,你可以找到一系列展示JSTL基本功能的编译成功示例。这些示例将帮助初学者快速掌握JSTL的核心概念和用法。下面我们将深入探讨JSTL的关键组件和主要功能: 1. **Core标签库**:这是JSTL中最...
表达式语言(EL - Expression Language)** EL是JSP 2.0引入的,它简化了在JSP中获取和操作对象属性的方式。例如,`${variable}`这样的表达式可以用来直接访问页面作用域、请求作用域等中的变量。在JSTL中,EL常常...
EL,全称为Expression Language,是JavaServer Pages(JSP)2.0引入的一种轻量级表达式语言。它的主要功能是提供一种简洁的方式来访问和操作JavaBeans属性、JSP作用域中的对象以及Java EE应用上下文中的数据。EL...
**JSTL(JavaServer Pages Standard Tag Library)入门标准教程** **一、JSTL概述** JSTL是由Apache软件基金会开发的一个JavaServer Pages(JSP)标准标签库,它提供了一系列标签来简化JSP页面的开发,使代码更加...
**一、JSTL入门** JSTL的引入旨在减少JSP页面中的脚本let和内联Java代码,使页面更加清晰,便于维护。核心标签库`core`提供了许多基本的控制结构和操作,如迭代、条件判断、URL处理等。 1. **核心标签库(core)**...
**JSTL(JavaServer Pages Standard Tag Library)**是Java Web开发中的一种标准标签库,它为JSP页面提供了一套强大的、可..."JSTL入门帮助文档"会详细讲解这些概念和用法,对初学者来说是一份非常有价值的参考资料。
### JSTL入门详解 **一、JSTL1.0概述** JSTL(JavaServer Pages Standard Tag Library,JavaServer页面标准标签库)1.0版本发布于2002年6月,旨在简化JSP(JavaServer Pages)页面的开发过程,减少对脚本代码的...
JSTL的出现是为了减少在JSP页面中使用过多的Java脚本和表达式语言,从而提升页面的结构清晰度。 **JSTL的主要组件包括:** 1. **Core标签库**:提供了处理基本页面流程控制、URL重写、字符串操作等功能的标签。 2. ...
EL表达式语言 JSTL标签库: JSP标准标签库 MVC程序架构思想&案例 [总结]Path路径问题 [总结]JavaWeb乱码问题 [转自IBM]中文编码问题 JDBC入门 Jdbc事务控制管理 常用数据库连接池 编写JDBC框架 客户信息管理系统 ...
**JSTL(JSP Standard Tag Library)**是Java服务器页面(JSP)的一个扩展,旨在简化JSP页面的开发,通过提供一组预定义的标签,使得开发者可以在不使用脚本语言的情况下处理业务逻辑。JSTL的出现是为了替代JSP页面...
**表达式语言(EL)** EL(Expression Language)是JSTL中的一个重要组成部分,它是基于ECMAScript和XPath的一种轻量级脚本语言。EL用于在JSP页面中检索和操作数据,其语法以`${}`为标识。EL可以访问页面范围内的...
- 详细介绍JSTL的核心组件——表达式语言(EL),包括语法特点、数据类型以及操作符。 - 展示如何使用EL来访问JSP页面中的变量、对象属性等。 - **第4章:条件控制** - 解释如何利用JSTL提供的条件标签来实现...