使用JavaServer Pages2.0开发Web应用
作者 Qusay H. Mahmoud July 2003
·JSP2.0
JSP2.0对比于JSP1.2来说,提供了一些有趣的新特点,从而使得Web应用设计人员和开发人员的生活更简单。JSP2.0的目标是让JSP更容易使用,更重要的是使用它而不需要学习Java语言。通过加入SimpleTag的新的扩展机制,JSP2.0简化了标记(Tag)APIs。
另外,还有一些其他的改进,以下是JSP2.0引入的新的关键特征。
1. 简单的表示语言EL(Expression Language),它的使用简化了JSP中的数据访问。它简化了基于JSP的Web应用的代码书写,可以不再使用传统的Java脚本和Java表达式了。
2. 定义可重用的定制行为的新句法,由开发者和页面人员在.tag和.tagx文件中描述。
3. XML句法也有实质的进步,加入了新的标准文件名扩展(标记文件.tagx和JSP文件.jspx)
本文将重点讲述EL、简易的标记API、和标记文件。我相信现有的JSP开发者将发现这些新特性十分有趣和实用。
·为什么从 1.2跳到2.0
原本JSR152中列出的版本为1.3。然而加入的这些新特性将对JSP应用的开发模型产生深远的影响,所以专家组觉得只要将主版本号升为2才能更适当的反映这些影响。当然新的版本号也有利于吸引开发者注意新特性。而且新的2.0与原有的1.2版本完全兼容,不会影响原有的应用。
·让我们开始吧!
为了使用JSP2.0,你需要支持JSP2.0和Servlet2.4的JSP容器。Jakarta Tomcat5.0支持新的JSP2.0和Servlet2.4,可以下载Tomcat或者jwsdp1.2。
·JSP表示语言(EL)
表示语言(EL)是为页面人员设计,它将JSP作用域属性提升成为商务逻辑和JSP页信息交流的标准方式。注意,虽然EL是JSP2.0的关键方面,但它不是通常意义的编程语言,它只是简单的数据访问语言,它的出现是为了方便绕过脚本语言和请求时的表达式的值而访问应用的数据。JSP2.0以前,页面人员必须使用表达式<%=aName%>访问系统的数据,就象下面的例子:
<someTags:aTag attribute="<%= pageContext.getAttribute("aName") %>">
或者JavaBean中的数据
<%= aCustomer.getAddress().getCountry() %>
表示语言允许页面人员使用简易句法访问对象。例如,获得一个简单变量的值,你可以使用
<someTags:aTag attribute="${aName}">
而获取JavaBean中的属性值,你将使用语句 ${aCustomer.address.country}
·访问应用数据
你可以使用三种形式访问应用数据:对象的属性、使用”.”操作符或者使用括号“[名称]”形式的数组元素。表达式${data}代表作用域变量data。你可以通过使用句点”.”或者是括号”[]”操作符从聚集中获取属性。
1. 句点操作符用于获取命名的属性。例如表达式${customer.name}表示customer域内的name属性。
2. 括号操作符也可以用来获取命名的属性,例如${customer[“name”]}。它还可以通过索引访问属性,${customer[0]}表示customer集合中的第一个元素。
表示语言将句点和括号统一对待。因此,${customer.name}和${customer[“name]”}意义相同。诚然所有的EL都使用${和}。EL使用PageContext.findAttribute(String)查询属性,如果属性不存在,则返回空值(null)。
·操作符
EL支持算术、关系和逻辑操作符,另外还有一个特殊的操作符用来判断对象是否为空。操作符在表1中列出。你可以使用empty操作符确定是否一个聚集或字符串为空或null。例如,${empty param.name}为真仅当名为param的请求参数不存在。Empty操作符可以和”!”联合使用,象${!empty param.name}为真如果param存在时。
表 1:EL操作符
操作符
描述
+
加
-
减
*
乘
/ or div
除
% or mod
模除(求余)
== or =
等于
!= or !=
不等于
< or lt
小于
> or gt
大于
<= or le
不大于
>= or ge
不小于
&& or and
逻辑与
|| or or
逻辑或
! or not
逻辑非
empty
检查为空否
a ? b : c
条件语句
·隐含对象
除开操作符,EL还定义了一系列隐含对象以支持应用数据的访问。隐含对象定义如表2所式
表 2:EL提供的隐含对象
隐含对象
内容
applicationScope
应用域变量集合
cookie
所有cookies的集合
header
HTTP请求头的字符串
headerValues
HTTP请求头的字符串集合
initParam
应用初始参数集合
pageContext
javax.servlet.jsp.PageContext对象
pageScope
页面域变量集合
param
请求参数的字符串
paramValues
请求参数的字符串
requestScope
请求域对象的集合
sessionScope
会话域对象的集合
·EL示例
Web页面人员可以在不了解Java的基础上使用EL开发。
添表的例子
隐含对象,$param[var]可以被用于读取表中的数据。见form.jsp代码
Code Sample 1: form.jsp
<HTML>
<HEAD>
<TITLE>Form Content</TITLE>
</HEAD>
<BODY>
<H3>Fill-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>
<P>
The Name is: ${param.name}
</BODY>
</HTML>
在这个例子中,当用户输入姓名并单击按钮”Submit Name”时,输入的姓名会在相同的页面显示。
·开发和使用函数(function)
EL允许你定义在表达式中调用的函数。函数必须在public class中定义为public static方法。一旦函数被开发了,它的签名必须在标记库描述符(TLD)中映射。为了说明函数的用法,我使用了简单的加法例子。首先,我写一段实现加法功能的Java代码,示例二显示了这个功能。
Code Sample 2: 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编译通过,下一步就是在TLD中映射函数签名。示例三说明了如何做。
Code Sample 4: Function Descriptor
<function>
<description>add x and y</description>
<name>add</name>
<function-class>jsp2.examples.el.Compute
</function-class>
<function-signature>int
add(java.lang.String,java.lang.String)
</function-signature>
</function>
现在,我们可以写JSP页面代码使用这个功能了。示例四显示一个表格,用户输入两个数并单击Add Numbers按钮,则功能Add被调用,结果显示在同一页上。
Code Sample 4: math.jsp
<%@ taglib prefix="my"
uri="http://jakarta.apache.org/tomcat/jsp2-example-taglib %>
<HEAD>
<TITLE>Functions</TITLE>
</HEAD>
<BODY>
<H3>Add Numbers</H3>
<P>
<FORM action="math.jsp" method="GET">
X = <input type="text" name="x" value="${param["x"]}">
<BR>
Y = <input type="text" name="y" value="${param["y"]}">
<input type="submit" value="Add Numbers">
</FORM>
<P>
The sum is: ${my:add(param["x"],param["y"])}
</BODY>
</HTML>
·标记处理器
JSP1.2中的标记处理器APIs因为脚本在标记体中的使用而很复杂。随着EL的出现,现在开发无脚本的JSP页面成为可能。出于这个目的,JSP2.0引入了被称为简单标记扩展的新型的标记扩展机制,它可以通过两步使用。
1. Java开发者:通过定义实现javax.servlet.jsp.tagext.SimpleTag接口的类。
2. 不了解Java的页面作者:通过使用标记文件。
这里有一个例子。代码示例5介绍了一个输出This is my first tag!信息的简单标记处理器。
Code Sample 5: HelloTag.java
package jsp2.examples.simpletag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
/**
* SimpleTag handler that prints "This is my first tag!"
*/
public class HelloTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
getJspContext().getOut().write("This is my first tag!");
}
}
一旦通过编译,下一步是在TLD中定义标记描述符。
Code Sample 6: Tag Descriptor
<tag>
<description>Prints this is my first tag</description>
<name>hello</name>
<tag-class>jsp2.examples.simpletag.HelloTag</tag-class>
<body-content>empty</body-content>
</tag>
最后,可以在JSP中使用我刚开发的这个标记。
Code Sample 7: helloworld.jsp
<%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %>
<HTML>
<HEAD>
<TITLE>Simple Tag Handler</TITLE>
</HEAD>
<BODY>
<H2>Simple Tag Handler</H2>
<P>
<B>My first tag prints</B>: <mytag:hello/>
</BODY>
</HTML>
·标记文件
使用简单标记扩展机制的另一种方法是通过使用标记文件。标记文件是一种原文件,它为页面作者提供了一种用来抽象化JSP代码段并通过定制行为(Custome Action)使这段代码可重用的方法。换句话说,标记文件允许JSP页面作者使用JSP句法创建可重用的标记库。标记文件所要求的文件扩展名是.tag。为了说明它有多容易,考虑示例8中的代码。
Code Sample 8: greetings.tag
Hello there. How are you doing?
创建了标记文件后,你可以使用这个定制行为书写JSP页面。作为示例,看看代码9所式的JSP。
Code Sample 9: chat.jsp
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<HTML>
<HEAD>
<TITLE>JSP 2.0 Examples - Hello World Using a Tag File</TITLE>
</HEAD>
<BODY>
<H2>Tag File Example</H2>
<P>
<B>The output of my first tag file is</B>: <tags:greetings/>
</BODY>
</HTML>
另一个标记文件例子
标记文件可以被用作模板(template)。考虑代码10描述的标记文件,display.tag。这个例子是从Tomcat5.0自带的Panel例子扩展来的。Attribute指令与TLD中的<attribute>元素类似;它用来定义定制行为的属性。
Code Sample 10: display.tag
<%@ attribute name="color" %>
<%@ attribute name="bgcolor" %>
<%@ attribute name="title" %>
<TABLE border="0" bgcolor="${color}">
<TR>
<TD><B>${title}</B></TD>
</TR>
<TR>
<TD bgcolor="${bgcolor}">
<jsp:doBody/>
</TD>
</TR>
</TABLE>
代码示例11说明一个简单的JSP页面如何使用display标记。
Code Sample 11: newsportal.jsp
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<HTML>
<HEAD>
<TITLE>Another Tag File Example</TITLE>
</HEAD>
<BODY>
<H2>News Portal: Another Tag File Example</H2>
<TABLE border="0">
<TR valign="top">
<TD>
<tags:display color="#ff0000" bgcolor="#ffc0c0"
title="Travel">
Last French Concorde Arrives in NY<br/>
Another Travel Headline<br/>
Yet Another Travel Headline<br/>
</tags:display>
</TD>
<TD>
<tags:display color="#00fc00" bgcolor="#c0ffc0"
title="Technology">
Java for in-flight entertainment<BR>
Another Technology Headline<BR>
Another Technology Headline<BR>
</tags:display>
</TD>
<TD>
<tags:display color="#ffcc11" bgcolor="#ffffcc"
title="Sports">
American Football<BR/>
NBA<BR/>
Soccer<BR/>
</tags:display>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
运行这个例子:
1. 将display.tag文件拷贝到<TOMCAT_HOME>\webapps\jsp-examples\WEB-INF\tag目录下。
2. 将newsportal.jsp保存在<TOMCAT_HOME>\webapps\jsp-examples\jsp2-tutorial目录下。
3. 启动tomcat服务器并在浏览器中请求newsportal.jsp页
现在,你应该在浏览器中看见如下显示
Figure 使用标记文件作为模板
·结论
JSP2.0使得动态Web页较之从前开发更快速,维护更简单。虽然JSP2.0中存在Java一词,但实际上页面作者可以完全不用学习Java语言开发出全新的动态网页。上述的例子说明了使用JSP2.0的新特性开发动态网页是多么的简单。
更多信息
JavaServer Pages Specification (JSR 152)
The Tomcat 5 Servlet/JSP Container
JavaServer Pages Standard Tag Library (JSTL)
Faster Development with JavaServer Pages Standard Tag Library (JSTL 1.0)