JSTL : 表达式语言
表 1 中列出了 11 个 EL 隐式对象的标识符。不要将这些对象与 JSP 隐式对象(一共只有九个)混淆,其中只有一个对象是它们所共有的。
类别 | 标识符 | 描述 |
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 操作特性和元素。
点运算符通常用于访问对象的特性。例如,在表达式 ${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"
键相关联的值。
最后,点运算符和方括号运算符可能实现某种程度的互换。例如,也可以使用 ${user["firstName"]}
来检索 user
对象的 firstName
特性,正如可以用 ${commands.dir}
获取与 commands
映射中的 "dir"
键相关联的值一样。
JSP 9个隐式对象:
前面的笔记中以对这部分内容有过记录.
URL 重写是由 <c:url>
操作自动执行的。如果 JSP 容器检测到一个存储用户当前会话标识的 cookie,那么就不必进行重写。但是,如果不存在这样的 cookie,那么 <c:url>
生成的所有 URL 都会被重写以编码会话标识。注:如果在随后的请求中存在适当的 cookie,那么 <c:url>
将停止重写 URL 以包含该标识。
如果为 var
属性提供了一个值(还可以同时为 scope
属性提供一个相应的值,这是可选的),那么将生成的 URL 赋值给这个限定了作用域的指定变量。否则,将使用当前的 JspWriter
输出生成的 URL。这种直接输出其结果的能力允许 <c:url>
标记作为值出现,例如,作为 HTML <a>
标记的 href
属性的值,如清单 13 中所示。
<a href="<c:url value='/content/sitemap.jsp'/>">View sitemap</a> |
最后,如果通过嵌套 <c:param>
标记指定了任何请求参数,那么将会使用 HTTP GET 请求的标准表示法将它们的名称和值添加到生成的 URL 后面。此外,还进行 URL 编码:为了生成有效的 URL,将对这些参数的名称或值中出现的任何字符适当地进行转换。清单 14 演示了 <c:url>
的这种行为。
<c:url value="/content/search.jsp"> <c:param name="keyword" value="${searchTerm}"/> <c:param name="month" value="02/2003"/> </c:url> |
清单 14 中的 JSP 代码被部署到一个名为 blog
的 servlet 上下文,限定了作用域的变量 searchTerm
的值被设置为 "core library"
。如果检测到了会话 cookie,那么清单 14 生成的 URL 将类似于清单 15 中的 URL。注:在前面添加上下文名称,而在后面附加请求参数。此外, keyword
参数值中的空格和 month
参数值中的斜杠都被按照 HTTP GET 参数的需要进行了编码(确切地说,空格被转换成了 +
,而斜杠被转换成了 %2F
序列)。
/blog/content/search.jsp?keyword=foo+bar&month=02%2F2003 |
当没有会话 cookie 时,生成的结果如清单 16 中所示。同样,servlet 上下文被添加到了前面,而 URL 编码的请求参数被附加到了后面。不过,除此以外还重写了基本 URL 以包含指定的会话标识。当浏览器发送用这种方式重写的 URL 请求时,JSP 容器自动抽取会话标识,并将请求与相应的会话进行关联。这样,需要会话管理的 J2EE 应用程序就无需依赖由应用程序用户启用的 cookie 了。
/blog/content/search.jsp;jsessionid=233379C7CD2D0ED2E9F3963906DB4290 ?keyword=foo+bar&month=02%2F2003 |
在tag文件中使用属性标签 :
在tag文件中,每个属性都必须用 attribute directive 申明.required attribute为true,那么这个JSP文件必须为这个属性指定值.required attribute默认是flase.
例题:
红色部分等价于<table cellpadding="5" cellspacing="0" border="1" >
因为header是个MAP类,h.key和h.value对应于接口 Map.Entry<K,V>的getValue() 和getKey()方法.
<CAPTION> 的作用是为表格标示一个标题列(HTML元素),如同在表格上方加一没有格线的打通列,通常用来存放表格标题。
<%@ tag body-content="empty" dynamic-attributes="dynattrs" %> <%@ attribute name="caption" required="true" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <table <c:forEach items="${dynattrs}" var="a"> ${a.key}="${a.value}" </c:forEach> > <caption>${caption}</caption> <tr> <th>Name</th> <th>Value</th> </tr> <c:forEach items="${header}" var="h"> <tr> <td>${h.key}</td> <td>${h.value}</td> </tr> </c:forEach> </table>
JSP page:
<%@ page contentType="text/html" %> <%@ taglib prefix="my" tagdir="/WEB-INF/tags/mytags" %> <html> <head> <title>Headers</title> </head> <body bgcolor="white"> <my:headers caption="Request Headers" border="1" cellspacing="0" cellpadding="5" /> </body> </html>