除了其他一些改进外,JSP 2.0引入的最主要的新特性包括:
1.一种简单的表达式语言(EL),能够用来容易地从JSP页面访问数据,这种表达式语言简化了基于JSP的不含脚本的应用程序的编写,不需要使用Java Scriptlet或者Java表达式;
2.用于直接使用JSP技术来定义可重用的自定义行为的新语法,该语法使用.tag和.tagx文件,这类文件可由开发人员或者网页作者编写;
3.XML语法得到了实质性的改进,增加了新的标准文件扩展名(.tagx用于标签文件,.jspx用于JSP文件)。
本文主要讨论表达式语言、简化的标签API和标签文件。相信目前的JSP开发人员将会发现这些重要的特性不但有趣,而且非常有用。
为何要从1.2跨越到2.0?
在Java规格请求(JSR 152)中版本号最初定为1.3。但是正如你将在后面看到的那样,由于这些新特性对JSP应用程序的开发模型产生了如此深刻的影响,专家组感到有必要把主版本号升级到2.0,这样才能充分反映这种影响。此外,新的版本号也有助于把开发人员的注意力吸引到这些有趣的新特性上来。令人欣慰的是,所有合法的JSP1.2页面同时也是合法的JSP2.0页面。
JSP 2.0起步
在着手学习JSP 2.0之前,你需要一个支持JSP2.0和Java Servlet 2.4规范的JSP环境。幸运的是,Jakarta Tomcat 5.0(alpha测试版)支持新的JSP2.0和Servlet 2.4规范,可以从http://jakarta.apache.org/builds/jakarta-tomcat/release/v5.0.4-alpha/下载并安装Tomcat 5.0。
JSP表达式语言
向JSP网页传递信息是通过JSP scoped属性和请求参数完成的。专门为网页作者量身定做的一种表达式语言(EL)把JSP scoped属性提升为从业务逻辑向JSP页面传递信息的标准方式。但是要注意,尽管这种表达式语言是JSP的一个重要特性,它并不是一种通用的程序语言。它仅仅是一种数据访问语言,可以方便地访问和处理应用程序数据,而无需使用scriptlet或者请求时(request-time)表达式的值。
在JSP2.0之前,网页作者只能使用表达式<%= aName %访问系统的值,比如下面的例子:
<someTags:aTag attribute="<%= pageContext.getAttribute("aName") %"
或者使用自定义JavaBeans组件的值:
<%= aCustomer.getAddress().getCountry() %
表达式语言允许网页作者使用简单的语法访问对象。比如要访问一个简单变量,可以像下面这样写:
<someTags:aTag attribute="${aName}"
而访问嵌套的JavaBeans属性,则可以像下面这样写:
${aCustomer.address.country}
你可能会问,这不是javascript的语法吗?完全正确!如果你使用过javascript,就会感到非常轻松,因为表达式语言正是借用了访问结构化数据的javascript语法。
访问应用程序数据
可以使用点号运算符(.)访问作为对象属性的应用程序数据,也可使用方括号运算符[‘name’]访问命名的数组元素。
表达式${data}表示名为data的scoped变量。可以使用点号(.)或方括号([])运算符从集合中检索属性值:
点号运算符用于访问命名的属性,比如表达式${customer.name}表示scoped变量customer的name属性;
方括号运算符可用于检索命名的属性,比如在${customer[“name”]}中。也可以通过${customers[0]}的形式来访问集合customers中的第一项。 表达式语言统一了对点号和方括号运算符的处理,因此${customer.name}与${customer[“name”]}是等价的。正如你看到的那样,表达式必须使用${和}包围起来。
EL的标识符求值方式是使用PageContext.findAttribute(String),把标识符作为一个属性来查找它的值。如果没有找到该属性,则返回null。
运算符
表达式语言支持算术运算符、关系运算符和逻辑运算符,以完成大多数的数据处理操作。此外,它还提供了一个用于测试一个对象是否为空的特殊运算符。运算符如表1所示。你可以使用empty运算符判断某个集合或字符串是否为空。比方说,只有当要求的命名参数param没有给出时,表达式${empty param.name}才返回真。Empty运算符可以与“!”运算符一起使用,比如${!empty param.name}当要求的命名参数param存在时返回真。
表1:表达式语言运算符
运算符
说明
+
加
-
减
*
乘
/ 或 div
除
% 或 mod
模(求余)
== 或 =
等于
!= 或 !=
不等于
< 或 lt
小于
或 gt
大于
<= 或 le
小于等于
= 或 ge
大于等于
&& 或 and
逻辑与
|| or or
逻辑或
! 或 not
逻辑非
empty
检查是否为空值
a ? b : c
条件运算符
隐含对象
除了运算符外,表达式语言还定义了一些隐含对象以支持网页作者访问需要的应用程序数据。表达式语言定义的隐含对象如表2所示,后面将给出使用这些隐含对象的一个例子。
表2:表达式语言中的隐含对象
隐含对象
内容
applicationScope
应用程序范围内的scoped变量组成的集合
cookie
所有cookie组成的集合
header
HTTP请求头部,字符串
headervalues
HTTP请求头部,字符串集合
initParam
全部应用程序参数名组成的集合
pageContext
当前页面的javax.servlet.jsp.PageContext对象
pageScope
页面范围内所有对象的集合
param
所有请求参数字符串组成的集合
paramvalues
所有作为字符串集合的请求参数
requestScope
所有请求范围的对象的集合
sessionScope
所有会话范围的对象的集合
表达式语言的例子
如你所言,网页作者无须学习Java也能够使用这种表达式语言。示例代码1显示了一些表达式的例子和隐含对象的使用。
代码示例1: ex1.jsp
要运行这个例子,请参照以下步骤,这里我们假定Tomcat 5.0安装在c:\tomcat5.0下。
切换目录到 c:\Tomcat5.0\webapps\jsp-examples
创建新目录,名字可以是任意的,比如jsp2-tutorial
切换到jsp2-tutorial
把ex1.jsp复制并保存到该目录下
启动Tomcat 5服务器:指向“开始”-“程序”-“Apache Tomcat 5.0”,单击“Apache Tomcat 5.0”来启动Tomcat
在浏览器中输入http://localhost:8080/jsp-examples/jsp2-tutorial/ex1.jsp
你将看到类似图1所示的画面。使用表达式语言就这么简单!
注意: 在本文中,所有的JSP文件都保存在c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial目录下。
--------------------------------------------------------------------------------
填充表单例子
隐含对象$paran[var]可用于读取填充表单的数据。代码示例2给出了一个简单的表单,该表单提示用户输入一个名字。
代码示例2: form.jsp
[code]<HTML<HEAD<TITLEForm Content</TITLE</HEAD
<BODY
<H3Fill-out-form</H3<P<FORM action="form.jsp" method="GET"
Name = <input type="text" name="name" value="${param['name']}"
<input type="submit" value="Submit Name"
</FORM
<PThe Name is: ${param.name}
</BODY</HTML[/code]
定义和使用函数
表达式语言允许你定义可在表达式中调用的函数。函数必须作为public类中的public static方法编写。函数一经定义,它的签名(signature)就映射到标签库描述符(TLD)中。
为了说明函数的使用,我们举一个简单的例子,把两个数相加。首先要编写求两数之和的Java方法代码,如代码示例3所示,这里定义了一个静态方法,它接收两个字符串参数,把它们解析成整数并返回它们的和。
代码示例3: Compute.java
package jsp2.examples.el;
import java.util.*;
public class Compute
{
public static int add(String x, String y) {
int a = 0;
int b = 0;
try {
a = Integer.parseInt(x);
b = Integer.parseInt(y);
}catch(Exception e) {}
return a + b;
}
}
用javac把这段代码编译成功后,下一步就要把函数的签名映射到标签库。代码示例4说明了如何把add函数映射到包含函数实现和函数签名的类。后面将说明把这段代码添加到哪儿。
代码示例4: 函数描述符
<function
<descriptionadd x and y</description
<nameadd</name
<function-classjsp2.examples.el.Compute</function-class
<function-signature
int
add (java.lang.String,java.lang.String)
</fun