直播中
一、 JSP 技術(shù)概述 在 Sun 正式發(fā)布 JSP(JavaServer Pages) 之后,這種新的 Web 應(yīng)用開發(fā)技術(shù)很快引起了人們的關(guān)注。 JSP 為創(chuàng)建高度動(dòng)態(tài)的 Web 應(yīng)用提供了一個(gè)獨(dú)特的開發(fā)環(huán)境。按照 Sun 的說法, JSP 能夠適應(yīng)市場(chǎng)上包括 Apache WebServer 、 IIS4.0 在內(nèi)的 85% 的服務(wù)器產(chǎn)品。即使您對(duì) ASP "一往情深",我們認(rèn)為,關(guān)注 JSP 的發(fā)展仍舊很有必要。 ㈠ JSP 與 ASP 的簡(jiǎn)單比較 JSP 與 Microsoft 的 ASP 技術(shù)非常相似。兩者都提供在 HTML 代碼中混合某種程序代碼、由語言引擎解釋執(zhí)行程序代碼的能力。在 ASP 或 JSP 環(huán)境下, HTML 代碼主要負(fù)責(zé)描述信息的顯示樣式,而程序代碼則用來描述處理邏輯。普通的 HTML 頁面只依賴于 Web 服務(wù)器,而 ASP 和 JSP 頁面需要附加的語言引擎分析和執(zhí)行程序代碼。程序代碼的執(zhí)行結(jié)果被重新嵌入到 HTML 代碼中,然后一起發(fā)送給瀏覽器。 ASP 和 JSP 都是面向 Web 服務(wù)器的技術(shù),客戶端瀏覽器不需要任何附加的軟件支持。 ASP 的編程語言是 VBScript 之類的腳本語言, JSP 使用的是 Java ,這是兩者最明顯的區(qū)別。此外, ASP 與 JSP 還有一個(gè)更為本質(zhì)的區(qū)別:兩種語言引擎用完全不同的方式處理頁面中嵌入的程序代碼。在 ASP 下, VBScript 代碼被 ASP 引擎解釋執(zhí)行;在 JSP 下,代碼被編譯成 Servlet 并由 Java 虛擬機(jī)執(zhí)行,這種編譯操作僅在對(duì) JSP 頁面的第一次請(qǐng)求時(shí)發(fā)生。 ㈡運(yùn)行環(huán)境 Sun 公司的 JSP 主頁在 http://www.javasoft.com/products/jsp/index.html ,從這里還可以下載 JSP 規(guī)范,這些規(guī)范定義了供應(yīng)商在創(chuàng)建 JSP 引擎時(shí)所必須遵從的一些規(guī)則。 執(zhí)行 JSP 代碼需要在服務(wù)器上安裝 JSP 引擎。此處我們使用的是 Sun 的 JavaServer Web Development Kit ( JSWDK )。為便于學(xué)習(xí),這個(gè)軟件包提供了大量可供修改的示例。安裝 JSWDK 之后,只需執(zhí)行 startserver 命令即可啟動(dòng)服務(wù)器。在默認(rèn)配置下服務(wù)器在端口 8080 監(jiān)聽,使用 http://localhost:8080 即可打開缺省頁面。 在運(yùn)行 JSP 示例頁面之前,請(qǐng)注意一下安裝 JSWDK 的目錄,特別是" work "子目錄下的內(nèi)容。執(zhí)行示例頁面時(shí),可以在這里看到 JSP 頁面如何被轉(zhuǎn)換成 Java 源文件,然后又被編譯成 class 文件(即 Servlet )。 JSWDK 軟件包中的示例頁面分為兩類,它們或者是 JSP 文件,或者是包含一個(gè)表單的 HTML 文件,這些表單均由 JSP 代碼處理。與 ASP 一樣, JSP 中的 Java 代碼均在服務(wù)器端執(zhí)行。因此,在瀏覽器中使用"查看源文件"菜單是無法看到 JSP 源代碼的,只能看到結(jié)果 HTML 代碼。所有示例的源代碼均通過一個(gè)單獨(dú)的" examples "頁面提供。 ㈢ JSP 頁面示例 下面我們分析一個(gè)簡(jiǎn)單的 JSP 頁面。您可以在 JSWDK 的 examples 目錄下創(chuàng)建另外一個(gè)目錄存放此文件,文件名字可以任意,但擴(kuò)展名必須為 .jsp 。從下面的代碼清單中可以看到, JSP 頁面除了比普通 HTML 頁面多一些 Java 代碼外,兩者具有基本相同的結(jié)構(gòu)。 Java 代碼是通過 < % 和 %> 符號(hào)加入到 HTML 代碼中間的,它的主要功能是生成并顯示一個(gè)從 0 到 9 的字符串。在這個(gè)字符串的前面和后面都是一些通過 HTML 代碼輸出的文本。 < HTML> < HEAD>< TITLE>JSP 頁面 < /TITLE>< /HEAD> < BODY> < %@ page language="java" %> < %! String str="0"; %> < % for (int i=1; i < 10; i++) { str = str + i; } %> JSP 輸出之前。 < P> < %= str %> < P> JSP 輸出之后。 < /BODY> < /HTML> 這個(gè) JSP 頁面可以分成幾個(gè)部分來分析。 首先是 JSP 指令。它描述的是頁面的基本信息,如所使用的語言、是否維持會(huì)話狀態(tài)、是否使用緩沖等。 JSP 指令由 < %@ 開始, %> 結(jié)束。在本例中,指令" < %@ page language="java" %> "只簡(jiǎn)單地定義了本例使用的是 Java 語言(當(dāng)前,在 JSP 規(guī)范中 Java 是唯一被支持的語言)。 接下來的是 JSP 聲明。 JSP 聲明可以看成是定義類這一層次的變量和方法的地方。 JSP 聲明由 < %! 開始, %> 結(jié)束。如本例中的" < %! String str="0"; %> "定義了一個(gè)字符串變量。在每一項(xiàng)聲明的后面都必須有一個(gè)分號(hào),就象在普通 Java 類中聲明成員變量一樣。 位于 < % 和 %> 之間的代碼塊是描述 JSP 頁面處理邏輯的 Java 代碼,如本例中的 for 循環(huán)所示。 最后,位于 < %= 和 %> 之間的代碼稱為 JSP 表達(dá)式,如本例中的" < %= str %> "所示。 JSP 表達(dá)式提供了一種將 JSP 生成的數(shù)值嵌入 HTML 頁面的簡(jiǎn)單方法。 會(huì)話狀態(tài)維持是 Web 應(yīng)用開發(fā)者必須面對(duì)的問題。有多種方法可以用來解決這個(gè)問題,如使用 Cookies 、隱藏的表單輸入域,或直接將狀態(tài)信息附加到 URL 中。 Java Servlet 提供了一個(gè)在多個(gè)請(qǐng)求之間持續(xù)有效的會(huì)話對(duì)象,該對(duì)象允許用戶存儲(chǔ)和提取會(huì)話狀態(tài)信息。 JSP 也同樣支持 Servlet 中的這個(gè)概念。 在 Sun 的 JSP 指南 中可以看到許多有關(guān)隱含對(duì)象的說明(隱含的含義是,這些對(duì)象可以直接引用,不需要顯式地聲明,也不需要專門的代碼創(chuàng)建其實(shí)例)。例如 request 對(duì)象,它是 HttpServletRequest 的一個(gè)子類。該對(duì)象包含了所有有關(guān)當(dāng)前瀏覽器請(qǐng)求的信息,包括 Cookies , HTML 表單變量等等。 session 對(duì)象也是這樣一個(gè)隱含對(duì)象。這個(gè)對(duì)象在第一個(gè) JSP 頁面被裝載時(shí)自動(dòng)創(chuàng)建,并被關(guān)聯(lián)到 request 對(duì)象上。與 ASP 中的會(huì)話對(duì)象相似, JSP 中的 session 對(duì)象對(duì)于那些希望通過多個(gè)頁面完成一個(gè)事務(wù)的應(yīng)用是非常有用的。 為說明 session 對(duì)象的具體應(yīng)用,接下來我們用三個(gè)頁面模擬一個(gè)多頁面的 Web 應(yīng)用。第一個(gè)頁面( q1.html )僅包含一個(gè)要求輸入用戶名字的 HTML 表單,代碼如下: < HTML> < BODY> < FORM METHOD=POST ACTION="q2.jsp"> 請(qǐng)輸入您的姓名: < INPUT TYPE=TEXT NAME="thename"> < INPUT TYPE=SUBMIT VALUE="SUBMIT"> < /FORM> < /BODY> < /HTML> 第二個(gè)頁面是一個(gè) JSP 頁面( q2.jsp ),它通過 request 對(duì)象提取 q1.html 表單中的 thename 值,將它存儲(chǔ)為 name 變量,然后將這個(gè) name 值保存到 session 對(duì)象中。 session 對(duì)象是一個(gè)名字 / 值對(duì)的集合,在這里,名字 / 值對(duì)中的名字為" thename ",值即為 name 變量的值。由于 session 對(duì)象在會(huì)話期間是一直有效的,因此這里保存的變量對(duì)后繼的頁面也有效。 q2.jsp 的另外一個(gè)任務(wù)是詢問第二個(gè)問題。下面是它的代碼: < HTML> < BODY> < %@ page language="java" %> < %! String name=""; %> < % name = request.getParameter("thename"); session.putValue("thename", name); %> 您的姓名是: < %= name %> < p> < FORM METHOD=POST ACTION="q3.jsp"> 您喜歡吃什么 ? < INPUT TYPE=TEXT NAME="food"> < P> < INPUT TYPE=SUBMIT VALUE="SUBMIT"> < /FORM> < /BODY> < /HTML> 第三個(gè)頁面也是一個(gè) JSP 頁面( q3.jsp ),主要任務(wù)是顯示問答結(jié)果。它從 session 對(duì)象提取 thename 的值并顯示它,以此證明雖然該值在第一個(gè)頁面輸入,但通過 session 對(duì)象得以保留。 q3.jsp 的另外一個(gè)任務(wù)是提取在第二個(gè)頁面中的用戶輸入并顯示它: < HTML> < BODY> < %@ page language="java" %> < %! String food=""; %> < % food = request.getParameter("food"); String name = (String) session.getValue("thename"); %> 您的姓名是: < %= name %> < P> 您喜歡吃: < %= food %> < /BODY> < /HTML> JavaBean 是一種基于 Java 的軟件組件。 JSP 對(duì)于在 Web 應(yīng)用中集成 JavaBean 組件提供了完善的支持。這種支持不僅能縮短開發(fā)時(shí)間(可以直接利用經(jīng)測(cè)試和可信任的已有組件,避免了重復(fù)開發(fā)),也為 JSP 應(yīng)用帶來了更多的可伸縮性。 JavaBean 組件可以用來執(zhí)行復(fù)雜的計(jì)算任務(wù),或負(fù)責(zé)與數(shù)據(jù)庫的交互以及數(shù)據(jù)提取等。如果我們有三個(gè) JavaBean ,它們分別具有顯示新聞、股票價(jià)格、天氣情況的功能,則創(chuàng)建包含所有這三種功能的 Web 頁面只需要實(shí)例化這三個(gè) Bean ,使用 HTML 表格將它們依次定位就可以了。 為說明在 JSP 環(huán)境下 JavaBean 的應(yīng)用,我們創(chuàng)建了一個(gè)名為 TaxRate 的 Bean 。它有兩個(gè)屬性,即 Product (產(chǎn)品)和 Rate (稅率)。兩個(gè) set 方法分別用來設(shè)置這兩個(gè)屬性,兩個(gè) get 方法則用于提取這兩個(gè)屬性。在實(shí)際應(yīng)用中,這種 Bean 一般應(yīng)當(dāng)從數(shù)據(jù)庫提取稅率值,此處我們簡(jiǎn)化了這個(gè)過程,允許任意設(shè)定稅率。下面是這個(gè) Bean 的代碼清單: package tax; public class TaxRate { String Product; double Rate; public TaxRate() { this.Product = "A001"; this.Rate = 5; } public void setProduct (String ProductName) { this.Product = ProductName; } public String getProduct() { return (this.Product); } public void setRate (double rateValue) { this.Rate = rateValue; } public double getRate () { return (this.Rate); } } 在 JSP 頁面中應(yīng)用上述 Bean 要用到 < jsp:useBean> 標(biāo)記。依賴于具體使用的 JSP 引擎的不同,在何處配置以及如何配置 Bean 的方法也可能略有不同。本文將這個(gè) Bean 的 .class 文件放在 c:jswdk-1.0examplesWEB-INFjspeans ax 目錄下,這里的 tax 是一個(gè)專門存放該 Bean 的目錄。下面是一個(gè)應(yīng)用上述 Bean 的示例頁面: < HTML> < BODY> < %@ page language="java" %> < jsp:useBean id="taxbean" scope="application" class="tax.TaxRate" /> < % taxbean.setProduct("A002"); taxbean.setRate(17); %> 使用方法 1 : < p> 產(chǎn)品 : < %= taxbean.getProduct() %> < br> 稅率 : < %= taxbean.getRate() %> < p> < % taxbean.setProduct("A003"); taxbean.setRate(3); %> < b> 使用方法 2 : < /b> < p> 產(chǎn)品 : < jsp:getProperty name="taxbean" property="Product" /> < br> 稅率 : < jsp:getProperty name="taxbean" property="Rate" /> < /BODY> < /HTML> 在 < jsp:useBean> 標(biāo)記內(nèi)定義了幾個(gè)屬性,其中 id 是整個(gè) JSP 頁面內(nèi)該 Bean 的標(biāo)識(shí), scope 屬性定義了該 Bean 的生存時(shí)間, class 屬性說明了該 Bean 的類文件(從包名開始)。 這個(gè) JSP 頁面不僅使用了 Bean 的 set 和 get 方法設(shè)置和提取屬性值,還用到了提取 Bean 屬性值的第二種方法,即使用 < jsp:getProperty> 標(biāo)記。 < jsp:getProperty> 中的 name 屬性即為 < jsp:useBean> 中定義的 Bean 的 id ,它的 property 屬性指定的是目標(biāo)屬性的名字。 事實(shí)證明, Java Servlet 是一種開發(fā) Web 應(yīng)用的理想構(gòu)架。 JSP 以 Servlet 技術(shù)為基礎(chǔ),又在許多方面作了改進(jìn)。 JSP 頁面看起來象普通 HTML 頁面,但它允許嵌入執(zhí)行代碼,在這一點(diǎn)上,它和 ASP 技術(shù)非常相似。利用跨平臺(tái)運(yùn)行的 JavaBean 組件, JSP 為分離處理邏輯與顯示樣式提供了卓越的解決方案。 JSP 必將成為 ASP 技術(shù)的有力競(jìng)爭(zhēng)者。 |