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 标识符看作引用限制了作用域的变量。
对于上述两种情况,都可允许表达式出现在方括号中。对嵌套表达式求值的结果将被作为下标或键,用来检索集合或数组的适当元素。和点运算符一样,方括号运算符也可以递归应用。这使得 el 能够从多维数组、嵌套集合或两者的任意组合中检索元素。此外,点运算符和方括号运算符还可以互操作。例如,如果数组的元素本身是对象,则可以使用方括号运算符来检索该数组的元素,并结合点运算符来检索该元素的一个特性(例如 ${ urls[3].protocol})。
假定 el 充当指定动态属性值的简化语言,el 存取器有一个有趣的功能(与 java 语言的存取器不同),那就是它们在应用于 null 时不抛出异常。如果应用 el 存取器的对象(例如,${ foo.bar} 和 ${ foo["bar"]} 中的 foo 标识符)是 null,那么应用存取器的结果也是 null。事实证明,在大多数情况下,这是一个相当有用的行为,不久您就会了解这一点。
目前,表达式语言仅可用于指定 jstl 定制标记中的动态属性值。但 jstl 1.0 表达式语言的一个扩展已经被提出,会把它包括到 jsp 2.0 中去,眼下正在进行最后评审。这个扩展将允许开发人员通过自己的定制标记来使用 el。页面作者将可以在目前允许使用 jsp 表达式的任何地方使用 el 表达式,譬如将动态值插入模板文本中:<p>your preferred time zone is ${ timezone}</p>。