利用JSP 2.0開(kāi)發(fā)Web應用程序
作者:未知 來(lái)源:轉載 發(fā)布時(shí)間:2005-9-16 17:36:41 發(fā)布人:acx
增大字體 顏色 默認 灰度 橄欖色 綠色 藍色 褐色 紅色
JSP(JavaServer Pages)技術(shù)是對Servlet的進(jìn)一步抽象,它由JCP(Java Community Process)開(kāi)發(fā),是用于生成動(dòng)態(tài)內容的開(kāi)放式的、可免費獲取的規范,也是J2EE(Java 2 Enterprise Edition)規范的重要組成部分。許多商業(yè)應用服務(wù)器如BEA WebLogic、IBM WebSphere、Live Jrun和Orion都支持JSP技術(shù)。
從機票預訂系統、銀行系統到購物系統,Web上到處都在應用JSP技術(shù)。新發(fā)布的2.0版是對JSP1.2的升級,增加了一些有趣的新特性。JSP2的目標是使動(dòng)態(tài)網(wǎng)頁(yè)的設計更加容易,而且無(wú)需學(xué)習Java編程語(yǔ)言。
本文內容包括:
提供具有豐富示例代碼的教程來(lái)使你熟悉JSP2.0 介紹JSP2.0的新特性 提供利用JSP2.0開(kāi)發(fā)應用程序的一些體會(huì ) 給出了一些示例代碼,對這些代碼稍加修改即可用于你自己的應用程序。
如果你還不熟悉JSP,那么直接從JSP2.0入手是一個(gè)不錯的主意。但是如果希望學(xué)習JSP1.2,也許你需要從
JSP教程開(kāi)始學(xué)習。
JSP 2.0
JSP 2.0是對JSP 1.2的升級,增加了幾個(gè)有趣的新特性,可以使Web應用程序設計人員和開(kāi)發(fā)人員的工作更容易一些。JSP 2.0的目標是比以前更易于使用,更重要的是無(wú)須學(xué)習Java語(yǔ)言本身就可以使用它。它增加了一種稱(chēng)為SimpleTag的新擴展機制來(lái)簡(jiǎn)化標簽API(Tag API)。
除了其他一些改進(jìn)外,JSP 2.0引入的最主要的新特性包括:
一種簡(jiǎn)單的表達式語(yǔ)言(EL),能夠用來(lái)容易地從JSP頁(yè)面訪(fǎng)問(wèn)數據,這種表達式語(yǔ)言簡(jiǎn)化了基于JSP的不含腳本的應用程序的編寫(xiě),不需要使用Java scriptlet或者Java表達式; 用于直接使用JSP技術(shù)來(lái)定義可重用的自定義行為的新語(yǔ)法,該語(yǔ)法使用.tag和.tagx文件,這類(lèi)文件可由開(kāi)發(fā)人員或者網(wǎng)頁(yè)作者編寫(xiě); 3XML語(yǔ)法得到了實(shí)質(zhì)性的改進(jìn),增加了新的標準文件擴展名(.tagx用于標簽文件,.jspx用于JSP文件)。
本文主要討論表達式語(yǔ)言、簡(jiǎn)化的標簽API和標簽文件。相信目前的JSP開(kāi)發(fā)人員將會(huì )發(fā)現這些重要的特性不但有趣,而且非常有用。
為何要從1.2跨越到2.0?
在Java規格請求(JSR 152)中版本號最初定為1.3。但是正如你將在后面看到的那樣,由于這些新特性對JSP應用程序的開(kāi)發(fā)模型產(chǎn)生了如此深刻的影響,專(zhuān)家組感到有必要把主版本號升級到2.0,這樣才能充分反映這種影響。此外,新的版本號也有助于把開(kāi)發(fā)人員的注意力吸引到這些有趣的新特性上來(lái)。令人欣慰的是,所有合法的JSP1.2頁(yè)面同時(shí)也是合法的JSP2.0頁(yè)面。
JSP 2.0起步
在著(zhù)手學(xué)習JSP 2.0之前,你需要一個(gè)支持JSP2.0和Java Servlet 2.4規范的JSP環(huán)境。幸運的是,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表達式語(yǔ)言
向JSP網(wǎng)頁(yè)傳遞信息是通過(guò)JSP scoped屬性和請求參數完成的。專(zhuān)門(mén)為網(wǎng)頁(yè)作者量身定做的一種表達式語(yǔ)言(EL)把JSP scoped屬性提升為從業(yè)務(wù)邏輯向JSP頁(yè)面傳遞信息的標準方式。但是要注意,盡管這種表達式語(yǔ)言是JSP的一個(gè)重要特性,它并不是一種通用的程序語(yǔ)言。它僅僅是一種數據訪(fǎng)問(wèn)語(yǔ)言,可以方便地訪(fǎng)問(wèn)和處理應用程序數據,而無(wú)需使用scriptlet或者請求時(shí)(request-time)表達式的值。
在JSP2.0之前,網(wǎng)頁(yè)作者只能使用表達式<%= aName %>訪(fǎng)問(wèn)系統的值,比如下面的例子:
<someTags:aTag attribute="<%= pageContext.getAttribute("aName") %>">
或者使用自定義JavaBeans組件的值:
<%= aCustomer.getAddress().getCountry() %>
表達式語(yǔ)言允許網(wǎng)頁(yè)作者使用簡(jiǎn)單的語(yǔ)法訪(fǎng)問(wèn)對象。比如要訪(fǎng)問(wèn)一個(gè)簡(jiǎn)單變量,可以像下面這樣寫(xiě):
<someTags:aTag attribute="${aName}">
而訪(fǎng)問(wèn)嵌套的JavaBeans屬性,則可以像下面這樣寫(xiě):
${aCustomer.address.country}
你可能會(huì )問(wèn),這不是javascript的語(yǔ)法嗎?完全正確!如果你使用過(guò)javascript,就會(huì )感到非常輕松,因為表達式語(yǔ)言正是借用了訪(fǎng)問(wèn)結構化數據的javascript語(yǔ)法。
注意:表達式語(yǔ)言最初是作為JSP標準標簽庫(JSTL)1.0的一部分而開(kāi)發(fā)的,JSTL是一種標準標簽庫,它提供對通用的、結構化的任務(wù)的支持,如迭代和條件、XML文檔處理、國際化和利用SQL訪(fǎng)問(wèn)數據庫等。JSTL規范是由JSR 52專(zhuān)家組開(kāi)發(fā)的。關(guān)于JSTL的介紹,請參見(jiàn)
Faster Development with JSTL(使用JSTL加速開(kāi)發(fā)).
訪(fǎng)問(wèn)應用程序數據
可以使用點(diǎn)號運算符(.)訪(fǎng)問(wèn)作為對象屬性的應用程序數據,也可使用方括號運算符[‘name’]訪(fǎng)問(wèn)命名的數組元素。
表達式${data}表示名為data的scoped變量??梢允褂命c(diǎn)號(.)或方括號([])運算符從集合中檢索屬性值:
點(diǎn)號運算符用于訪(fǎng)問(wèn)命名的屬性,比如表達式${customer.name}表示scoped變量customer的name屬性; 方括號運算符可用于檢索命名的屬性,比如在${customer[“name”]}中。也可以通過(guò)${customers[0]}的形式來(lái)訪(fǎng)問(wèn)集合customers中的第一項。
表達式語(yǔ)言統一了對點(diǎn)號和方括號運算符的處理,因此${customer.name}與${customer[“name”]}是等價(jià)的。正如你看到的那樣,表達式必須使用${和}包圍起來(lái)。
EL的標識符求值方式是使用PageContext.findAttribute(String),把標識符作為一個(gè)屬性來(lái)查找它的值。如果沒(méi)有找到該屬性,則返回null。
運算符
表達式語(yǔ)言支持算術(shù)運算符、關(guān)系運算符和邏輯運算符,以完成大多數的數據處理操作。此外,它還提供了一個(gè)用于測試一個(gè)對象是否為空的特殊運算符。運算符如表1所示。你可以使用empty運算符判斷某個(gè)集合或字符串是否為空。比方說(shuō),只有當要求的命名參數param沒(méi)有給出時(shí),表達式${empty param.name}才返回真。Empty運算符可以與“!”運算符一起使用,比如${!empty param.name}當要求的命名參數param存在時(shí)返回真。
表1:表達式語(yǔ)言運算符
運算符
說(shuō)明
+
加
-
減
*
乘
/ 或 div
除
% 或 mod
模(求余)
== 或 =
等于
!= 或 !=
不等于
< 或 lt
小于
> 或 gt
大于
<= 或 le
小于等于
>= 或 ge
大于等于
&& 或 and
邏輯與
|| or or
邏輯或
! 或 not
邏輯非
empty
檢查是否為空值
a ? b : c
條件運算符
隱含對象
除了運算符外,表達式語(yǔ)言還定義了一些隱含對象以支持網(wǎng)頁(yè)作者訪(fǎng)問(wèn)需要的應用程序數據。表達式語(yǔ)言定義的隱含對象如表2所示,后面將給出使用這些隱含對象的一個(gè)例子。
表2:表達式語(yǔ)言中的隱含對象
隱含對象
內容
applicationScope
應用程序范圍內的scoped變量組成的集合
cookie
所有cookie組成的集合
header
HTTP請求頭部,字符串
headerValues
HTTP請求頭部,字符串集合
initParam
全部應用程序參數名組成的集合
pageContext
當前頁(yè)面的javax.servlet.jsp.PageContext對象
pageScope
頁(yè)面范圍內所有對象的集合
param
所有請求參數字符串組成的集合
paramValues
所有作為字符串集合的請求參數
requestScope
所有請求范圍的對象的集合
sessionScope
所有會(huì )話(huà)范圍的對象的集合
表達式語(yǔ)言的例子
如你所言,網(wǎng)頁(yè)作者無(wú)須學(xué)習Java也能夠使用這種表達式語(yǔ)言。示例代碼1顯示了一些表達式的例子和隱含對象的使用。
代碼示例1: ex1.jsp
要運行這個(gè)例子,請參照以下步驟,這里我們假定Tomcat 5.0安裝在c:\tomcat5.0下。
切換目錄到 c:\Tomcat5.0\webapps\jsp-examples 創(chuàng )建新目錄,名字可以是任意的,比如jsp2-tutorial 切換到j(luò )sp2-tutorial 把ex1.jsp復制并保存到該目錄下 啟動(dòng)Tomcat 5服務(wù)器:指向“開(kāi)始”->“程序”->“Apache Tomcat 5.0”,單擊“Apache Tomcat 5.0”來(lái)啟動(dòng)Tomcat 在瀏覽器中輸入http://localhost:8080/jsp-examples/jsp2-tutorial/ex1.jsp
你將看到類(lèi)似圖1所示的畫(huà)面。使用表達式語(yǔ)言就這么簡(jiǎn)單!
圖1:JSP表達式語(yǔ)言和隱含對象
注意: 在本文中,所有的JSP文件都保存在c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial目錄下。
填充表單例子
隱含對象$paran[var]可用于讀取填充表單的數據。代碼示例2給出了一個(gè)簡(jiǎn)單的表單,該表單提示用戶(hù)輸入一個(gè)名字。
代碼示例2: 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>
在本例中,當用戶(hù)輸入名字并單擊“提交”按鈕時(shí),輸入的名字就會(huì )顯示同一頁(yè)面中的“The Name is:”字樣后面,如圖2所示。
同樣,運行這個(gè)例子只需要把form.jsp復制到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial下并用瀏覽器打開(kāi)它。
圖2:表單處理
定義和使用函數
表達式語(yǔ)言允許你定義可在表達式中調用的函數。函數必須作為public類(lèi)中的public static方法編寫(xiě)。函數一經(jīng)定義,它的簽名(signature)就映射到標簽庫描述符(TLD)中。
為了說(shuō)明函數的使用,我們舉一個(gè)簡(jiǎn)單的例子,把兩個(gè)數相加。首先要編寫(xiě)求兩數之和的Java方法代碼,如代碼示例3所示,這里定義了一個(gè)靜態(tài)方法,它接收兩個(gè)字符串參數,把它們解析成整數并返回它們的和。
代碼示例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說(shuō)明了如何把add函數映射到包含函數實(shí)現和函數簽名的類(lèi)。后面將說(shuō)明把這段代碼添加到哪兒。
代碼示例4: 函數描述符
<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>
現在我們就可以編寫(xiě)一個(gè)JSP頁(yè)面來(lái)使用這個(gè)函數。代碼示例5是包含兩個(gè)字段的一個(gè)表單,用戶(hù)輸入兩個(gè)數字并按下“求和”按鈕,就會(huì )調用上面的函數并把兩個(gè)數相加,結果在同一個(gè)頁(yè)面中顯示出來(lái)。
代碼示例5: 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>
要運行這個(gè)例子:
復制Compute.java并保存到C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\classes\jsp2\examples\el下; 使用javac編譯Compute.java; 編輯文件C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\jsp2\jsp2-example-taglib.tld,把代碼示例4中的代碼段添加到文件中最后一個(gè)</function>標簽之后,</taglib>標簽之前; 復制math.jsp并保存到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial下; 用瀏覽器打開(kāi)該文件。
如果一切正常,應該會(huì )看到類(lèi)似如圖3所示的窗口。
圖3:使用函數
標簽處理器
JSP 1.2中傳統的標簽處理API由于允許標簽體中包含scriptlet而變得復雜,但是現在利用表達式語(yǔ)言可以編寫(xiě)不含scriptlet的JSP網(wǎng)頁(yè)。最終,JSP 2.0引入了一種新的標簽擴展機制,稱(chēng)為“簡(jiǎn)單標簽擴展”,這種機制有兩種使用方式:
Java開(kāi)發(fā)人員可以定義實(shí)現接口javax.servlet.jsp.tagext.SimpleTag的類(lèi); 不懂Java的網(wǎng)頁(yè)編寫(xiě)人員則可以使用標簽文件。
首先來(lái)看第一種方式,代碼示例6給出了一個(gè)簡(jiǎn)單的標簽處理器,它的作用僅僅是打印“This is my first tag! ”。
代碼示例6: 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中定義一個(gè)標簽描述符,下面是標簽描述符的例子。
代碼示例7: 標簽描述符
<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>
最后再編寫(xiě)一個(gè)使用上述標簽的JSP頁(yè)面文件,見(jiàn)代碼示例8。
代碼示例8: 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>
要運行這個(gè)例子:
復制HelloTg.java并保存到C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\classes\jsp2\examples\simpletag下; 使用javac編譯HelloTag.java; 把代碼示例7中的標簽描述符添加到文件C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\jsp2\jsp2-example-taglib.tld中的</taglib>之前; 復制helloworld.jsp并保存到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial目錄中; 用瀏覽器打開(kāi)helloworld.jsp。
如果一切正常,應該會(huì )看到類(lèi)似如圖4所示的畫(huà)面。
圖4:簡(jiǎn)單標簽處理器
標簽文件
使用簡(jiǎn)單標簽擴展機制的另一種方法是通過(guò)標簽文件。標簽文件是一種資源文件,網(wǎng)頁(yè)作者可以利用它抽取一段JSP代碼,通過(guò)定制功能來(lái)實(shí)現代碼的復用。換句話(huà)說(shuō),標簽文件允許JSP網(wǎng)頁(yè)作者使用JSP語(yǔ)法創(chuàng )建可復用的標簽庫。標簽文件的擴展名必須是“.tag”。
為說(shuō)明使用標簽文件是多么容易,考慮一下代碼示例9。沒(méi)錯,這就是一個(gè)標簽文件!
代碼示例9: greetings.tag
Hello there. How are you doing?
一旦定義了標簽文件,就可以在JSP網(wǎng)頁(yè)的編寫(xiě)中使用這種定制的功能。比如代碼示例10中的JSP網(wǎng)頁(yè)。
代碼示例10: 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>
要運行這個(gè)例子:
復制標簽文件greetings.tags并保存在c:\Tomcat5.0\webapps\jsp-examples\WEB-INF\tags 目錄下; 復制JSP網(wǎng)頁(yè)文件char.jsp并保存在c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial 目錄下; 用瀏覽器打開(kāi)chat.jsp文件。
如果一切正常,應該會(huì )看到類(lèi)似如圖5所示的窗口。
圖5:簡(jiǎn)單的標簽文件
注意: 重要的是要注意到這里沒(méi)有為問(wèn)候標簽編寫(xiě)TLD,而是創(chuàng )建了一個(gè)標簽文件并放在特殊的目錄中,然后用taglib指令導入并直接使用它。
另一個(gè)標簽文件的例子
標簽文件可以作為模板使用??紤]代碼示例11中的標簽文件display.tag,這個(gè)例子是根據Tomcat 5.0中的面板的例子改寫(xiě)的。指令attribute類(lèi)似于TLD中的<attribute>元素,允許聲明自定義的動(dòng)作屬性。
代碼示例11: 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>
代碼示例12給出了使用上述標簽的一個(gè)簡(jiǎn)單的JSP頁(yè)面。
代碼示例12: 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>
要運行這個(gè)例子:
復制文件display.tag并保存在c:\Tomcat5.0\webapps\jsp-examples\WEB-INF\tag 下; 復制文件newsportal.jsp并保存到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial下; 用瀏覽器打開(kāi)newsportal文件。
結果應該會(huì )得到與圖6類(lèi)似的畫(huà)面。
圖6:把標簽文件用作模板
結論
JSP 2.0使得快速開(kāi)發(fā)和維護動(dòng)態(tài)網(wǎng)頁(yè)比以前更加容易,盡管“Java”一詞出現在JSP中,但使用JSP2.0,網(wǎng)頁(yè)作者無(wú)須學(xué)習Java程序語(yǔ)言本身,就能開(kāi)發(fā)出全新的動(dòng)態(tài)網(wǎng)頁(yè)。本文中的例子說(shuō)明了使用JSP2.0的新特性開(kāi)發(fā)動(dòng)態(tài)網(wǎng)頁(yè)是多么容易。