国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
用 Eclipse、WTP 和 Derby 構(gòu)建 Web 應(yīng)用程序

級(jí)別: 中級(jí)

Susan L. Cline, Cloudscape 社區(qū)開發(fā)人員, IBM

2005 年 9 月 01 日

使用 Eclipse、Web Tools Platform (WTP) for Eclipse、Derby 和 Jakarta-Tomcat 構(gòu)建動(dòng)態(tài) Web 應(yīng)用程序是件很容易的事。本文將帶您學(xué)習(xí)如何安裝和配置所有這些必需的開放源碼組件,并使用 JSP 和 servlet 構(gòu)建一個(gè)完整的用于向 Derby 數(shù)據(jù)庫存儲(chǔ)和獲取信息的 Web 應(yīng)用程序。

簡介

Eclipse 是使用 Java 技術(shù)開發(fā) Web 應(yīng)用程序的理想平臺(tái)。動(dòng)態(tài) Web 應(yīng)用程序的 3 層設(shè)計(jì)非常適合與運(yùn)行在 servlet 容器(例如 Apache Jakarta Tomcat)中的 JSP 和 Servlet 相結(jié)合。持久數(shù)據(jù)層可以適當(dāng)?shù)赜?Derby 數(shù)據(jù)庫提供。用于開發(fā) J2EE 和 Web 應(yīng)用程序的 Eclipse Web Tools Platform (WTP) 項(xiàng)目工具集,加上 Derby Eclipse 插件,可以提供快速而簡便的 Web 開發(fā)。

本文討論 WTP 提供的一些功能、Derby 數(shù)據(jù)庫插件以及一個(gè)完整的示例應(yīng)用程序,該應(yīng)用程序使用了 JSP、JavaServer Pages Standard Tag Library (JSTL) 和 Servlets。這個(gè)示例應(yīng)用程序是一個(gè)虛擬的、經(jīng)過簡化的航線機(jī)票預(yù)訂系統(tǒng)。

為了更好地利用本文,您應(yīng)該理解 JSP、JSTL 和 Servlet 技術(shù)的基本知識(shí),理解簡單的 SQL,并對(duì) Eclipse 有一定的了解。本文中還使用了 WTP 的一些特性,但本文不是關(guān)于 WTP 工具的全面教程。要了解更多關(guān)于這些主題方面的知識(shí),請(qǐng)參考本文最后給出的 參考資料 列表。如果您已經(jīng)知道 WTP 的一些背景,并且想直接開始下載所有必需的軟件,那么請(qǐng)略過 軟件需求 小節(jié)。否則,請(qǐng)閱讀下一小節(jié),以了解 WTP 是什么,以及如何在 Eclipse 中使用其中一些組件來開發(fā)示例應(yīng)用程序。

IBM Cloudscape 是 Apache Derby 開放源碼數(shù)據(jù)庫的商業(yè)發(fā)行版。如果沒有引用特定的文件或名稱,那么這兩個(gè)名稱在本文中可以互換使用。





Eclipse WTP 項(xiàng)目

Eclipse Web Tools Platform (WTP) 項(xiàng)目允許 Eclipse 用戶開發(fā) J2EE Web 應(yīng)用程序。這個(gè)平臺(tái)中包括了多個(gè)編輯器、圖形編輯器、特性、構(gòu)建器、一個(gè) Web 服務(wù)向?qū)?、?shù)據(jù)庫訪問和查詢工具以及其他組件。該項(xiàng)目提供了大量的工具。而在使用 Derby 作為后臺(tái)數(shù)據(jù)庫構(gòu)建一個(gè) Web 應(yīng)用程序時(shí),只會(huì)演示其中有限的幾種工具。

在 www.eclipse.org/webtools 上 WTP 的特許權(quán)定義如下:“... 構(gòu)建有用的工具和一個(gè)通用的、可擴(kuò)展的且基于標(biāo)準(zhǔn)的工具平臺(tái),在這個(gè)平臺(tái)上,軟件供應(yīng)商可以創(chuàng)建用于產(chǎn)生支持 Web 的應(yīng)用程序的專門的、不同的解決方案?!北疚牟挥懻摓檫@個(gè)平臺(tái)構(gòu)建新的工具,而是使用它作為一個(gè)開放的平臺(tái),以便使用開放源碼組件構(gòu)建 Web 應(yīng)用程序。

Web Standard Tools 和 J2EE Standard Tools

WTP 分為兩個(gè)子項(xiàng)目,Web Standard Tools 和 J2EE Standard Tools。Web Standard Tools (WST) 項(xiàng)目為多層 Web 應(yīng)用程序提供公共基礎(chǔ)設(shè)施。它提供了一個(gè)服務(wù)器視圖,使您可以發(fā)布在 Eclipse 中創(chuàng)建的資源,并且在一個(gè)服務(wù)器上運(yùn)行它們。WST 不包括用于 Java 語言的特定工具,也不包括用于特定于 Web 框架的技術(shù)的特定工具。

J2EE Standard Tools (JST) 項(xiàng)目提供工具,用于簡化包括 EJB、Servlet、JSP、JDBC、 Web 服務(wù)等等在內(nèi)的 J2EE API 的開發(fā)。J2EE Standard Tools 項(xiàng)目以 Web Standard Tools 項(xiàng)目提供的 Server Tools 支持為基礎(chǔ),包括 servlet 和 EJB 容器。

下一節(jié)討論在構(gòu)建和運(yùn)行示例應(yīng)用程序時(shí)所需的軟件組件。






Web 應(yīng)用程序的組件

示例應(yīng)用程序使用了以下軟件組件和技術(shù):

  • Eclipse
    • 使用 IDE 編寫和運(yùn)行示例應(yīng)用程序。它是開發(fā)和構(gòu)建 Java 應(yīng)用程序的基礎(chǔ)。
    • 使用 Eclipse 附帶的 Java Development Tools (JDT) 編譯屬于應(yīng)用程序一部分的 Java 類。
  • WTP
    • 使用編輯器創(chuàng)建 JSP 文件。該編輯器包括 JSP 語法的內(nèi)容輔助。
    • 使用 Servers 視圖啟動(dòng)和停止外部的 Jakarta Tomcat servlet 引擎。
    • 使用 J2EE 透視圖創(chuàng)建動(dòng)態(tài) Web 應(yīng)用程序,這個(gè)動(dòng)態(tài) Web 應(yīng)用程序裝配和配置 J2EE Web 應(yīng)用程序,包括與所有 J2EE Web 應(yīng)用程序相同的標(biāo)準(zhǔn)結(jié)構(gòu)和部署描述符。
    • 通過 Database Explorer 視圖創(chuàng)建一個(gè)到 Derby 數(shù)據(jù)庫的連接。
  • Derby 插件
    • 添加 Derby 特性到動(dòng)態(tài) Web 項(xiàng)目,以便將 JAR 文件包括在項(xiàng)目中。
    • 在應(yīng)用程序開發(fā)期間啟動(dòng)和停止 Derby 網(wǎng)絡(luò)服務(wù)器。
    • 使用 ij SQL 查詢工具運(yùn)行 SQL 查詢。
    • 將項(xiàng)目的 derby.system.home 屬性設(shè)置為指向數(shù)據(jù)庫。
  • JavaServer Pages Standard Tag Library (JSTL)
    • 這個(gè)標(biāo)記庫使基于 JSP 的應(yīng)用程序可以使用一個(gè)標(biāo)準(zhǔn)標(biāo)記庫來執(zhí)行常見的任務(wù)。示例應(yīng)用程序使用這些標(biāo)記來執(zhí)行諸如迭代和數(shù)據(jù)庫訪問之類的任務(wù)。在 JSP 中還使用了 EL(Expression Language,表達(dá)式語言),這是一種腳本語言。
  • Apache Jakarta Tomcat servlet 引擎
    • 運(yùn)行由 JSP 和 Servlet 組成的 Web 應(yīng)用程序。
    • 提供對(duì) Servlet 2.4 和 JSP 2.0 API 的支持,包括對(duì) EL 的支持。
    • 提供對(duì)在 Web 應(yīng)用程序的部署描述符中將 Derby 數(shù)據(jù)庫定義為一個(gè) Data Source 的支持。

 






軟件需求

本節(jié)中描述的軟件可以免費(fèi)下載,在運(yùn)行例子和構(gòu)建示例 Web 應(yīng)用程序之前,必須安裝這些軟件。

以下兩種 Java 開發(fā)工具箱 之一:

  • IBM SDK version 1.4.2 或更高版本。
  • Sun JDK version 1.4.2 或更高版本。

 

Eclipse 和 WTP。您可以下載一個(gè)包括 Eclipse SDK、所有 WTP 先決條件以及 WTP 本身的 zip 文件。在 Windows 上,這個(gè)文件的文件名為 wtp-all-in-one-0.7-win32.zip。如果您喜歡下載 Linux 上的版本,那就是 wtp-all-in-one-0.7-linux-gtk.tar.gz 文件。您可以從 eclipse.org 下載其中任何一個(gè)文件(見 參考資料)。

如果您已經(jīng)安裝了 Eclipse,或者安裝了 WTP 的一些先決條件,那么您可以比較下面列出的 wtp-all-in-one zip 文件中包含的插件版本。而且, Download 頁面也列出了 0.7 WTP 的先決條件,所以您要確保安裝的組件至少能跟上這里列出的版本。如果可供下載的版本不同于下面列出的版本,那么請(qǐng)下載 WTP 站點(diǎn)上建議的版本。

  • Eclipse 3.1, for Windows:eclipse-SDK-3.1-win32.zip
  • EMF SDK:emf-sdo-xsd-SDK-2.1.0.zip
  • GEF SDK:GEF-SDK-3.1.zip
  • Java EMF Model Runtime:JEM-SDK-1.1.zip
  • Web Tools Platform:wtp-0.7.zip

Derby 數(shù)據(jù)庫 Eclipse 插件(apache.org 提供了 zip 文件,見 參考資料)。Apache Derby 數(shù)據(jù)庫最近發(fā)布了數(shù)據(jù)庫引擎的 10.1 版。為了在 Eclipse 3.1 上運(yùn)行,需要以下版本的插件:

  • Derby Core 插件,Version 10.1.1
  • Derby UI 插件,Version 1.1.0

 

Apache Jakarta Tomcat。下載 Version 5.0.28 (見 參考資料)。

JavaServer Pages Standard Tag Library (JSTL)。從 Apache Jakarta Project 下載 Standard 1.1 Taglib,jakarta-taglibs-standard-1.1.2.zip(見 參考資料)。

示例應(yīng)用程序源代碼和 WAR 文件

  • WAR 文件就是 Web Application Archive,它是打包和部署 J2EE Web 應(yīng)用程序的標(biāo)準(zhǔn)單元。所有遵從 J2EE 的 servlet 容器都接受 WAR 文件,并且可以部署這些文件。請(qǐng)下載 LowFareAir.war 文件到您的文件系統(tǒng)中(見 下載)。
  • 下載 zip 文件 LowFareDataSQL.zip,該文件包含 Derby 數(shù)據(jù)庫和訪問 airlinesDB 數(shù)據(jù)庫的示例 SQL 文件(見 下載)。

 






軟件配置

下載了所有必需的軟件之后,便需要配置它們,以便可以構(gòu)建應(yīng)用程序。

安裝 JDK

如果還沒有安裝 1.4.2 或更高版本的 JDK,那么安裝它。這里需要的是 JDK,而不是 JRE。

安裝 Eclipse 和 WTP

通過將 wtp-all-in-one-0.7-win32.zip 解壓到一個(gè)您想放置 Eclipse 的目錄中,便可以安裝 Eclipse。如果已經(jīng)安裝了 Eclipse,并且您下載了前面列出的各個(gè)組件,那么將那些組件解壓到 Eclipse 主目錄,因?yàn)樗鼈兌际遣寮?,這些組件將安裝到 Eclipse 的插件目錄。

安裝和配置 Jakarta Tomcat

將 Jakarta Tomcat 解壓或安裝到與 Eclipse 安裝目錄不同的一個(gè)目錄。

現(xiàn)在需要配置 Eclipse,以便在使用 WTP 的 Eclipse 中運(yùn)行 Tomcat 作為服務(wù)器。為此:

  • 訪問 http://www.eclipse.org/webtools/ 并選擇 WTP Community 下的教程鏈接。
  • 在 Tutorials 頁面,選擇名為“Building a School Schedule Web Application”的教程。
  • 遵循該教程“Installing the Tomcat Runtime in Eclipse”小節(jié)中的所有說明。對(duì)于這個(gè)示例 Web 應(yīng)用程序,不需要完成整個(gè)教程。

 

安裝 Derby 插件

將兩個(gè)文件(Derby Core 和 UI 插件的 zip 文件)都解壓到 Eclipse 主目錄下的插件目錄。Derby 插件附帶了關(guān)于如何使用這些插件的所有功能的完整的教程和例子。為了訪問幫助,請(qǐng)選擇 Help > Help Contents > Derby Plug-ins User Guide。






應(yīng)用程序設(shè)計(jì)

LowFareAir Web 應(yīng)用程序遵從標(biāo)準(zhǔn)的 3 層設(shè)計(jì)模型,由表示層、業(yè)務(wù)邏輯和控制層和數(shù)據(jù)或持久層組成。JSP 包括 JSTL 標(biāo)記庫,提供了 UI 或表示層。Servlets 和 java 支持類提供應(yīng)用程序的業(yè)務(wù)邏輯和流控制。而 Derby 數(shù)據(jù)庫及 JavaBeans 則提供數(shù)據(jù)層。下面的圖說明了這一點(diǎn)。


圖 1. 示例應(yīng)用程序設(shè)計(jì)

關(guān)于從表示層訪問數(shù)據(jù)層的注意事項(xiàng)

以 JSP 表示的表示層通常不應(yīng)該直接與數(shù)據(jù)層交互,因此也不應(yīng)該進(jìn)行數(shù)據(jù)庫查詢。該應(yīng)用程序的設(shè)計(jì)遵從公認(rèn)的范例,只有第一個(gè) JSP 除外。為了快速開發(fā)原型,將數(shù)據(jù)庫訪問合并到視圖層,打破數(shù)據(jù)與視圖嚴(yán)格分離的限制,這是可以接受的。第一個(gè) JSP,即 Welcome.jsp,使用 JSTL SQL 庫從該頁面發(fā)出一個(gè) SQL 查詢,因而同時(shí)占據(jù)了表示層和數(shù)據(jù)層。

其他 JSP 僅僅充當(dāng)表示層,它們將所有的數(shù)據(jù)處理任務(wù)都遞交給 Servlet,由這些 Servlet 與 Derby 數(shù)據(jù)庫交互。如果您有興趣在將來的 Web 應(yīng)用程序的原型開發(fā)中使用這種方法學(xué),那么這里展示了一個(gè) JSTL SQL 庫的例子,但是對(duì)于生產(chǎn)環(huán)境,不建議這么做。






LowFare Air 示例應(yīng)用程序

這個(gè)示例應(yīng)用程序允許新用戶的注冊(cè),并允許已有用戶登錄到這個(gè)應(yīng)用程序。用戶登錄以后,應(yīng)用程序展示出很多的航班,以供用戶訂票。由于只提供直達(dá)航班,所以要檢查用戶所選的航班,看出發(fā)地與目的地之間是否有直達(dá)航班。如果有這樣的航班,那么用戶就可以選擇預(yù)訂這個(gè)航班的機(jī)票。最后,用戶可以看到通過 LowFare Air 預(yù)訂的所有航班的歷史記錄。

示例應(yīng)用程序的流程由以下步驟組成:

  • 用戶注冊(cè)或驗(yàn)證
    • 用于應(yīng)用程序這一部分的 JSP 是 Welcome.jsp、Login.jsp 和 Register.jsp。
    • LoginServlet 擔(dān)任控制器 —— 或者在 Derby 數(shù)據(jù)庫的 APP.USERS 表中驗(yàn)證用戶的名稱,或者將用戶的名稱插入到這個(gè)表中。
    • 注冊(cè)成功之后,設(shè)置一個(gè)持久的 cookie;登錄成功后,將客戶機(jī)的用戶 ID 添加到會(huì)話中。
  • 檢索和選擇航班
    • Welcome.jsp 用于選擇航班,而 GetFlights.jsp 則用于檢索航班。
    • CheckFlightsServlet 擔(dān)任控制器。如果在選擇的兩個(gè)城市之間存在航班,那么將航班信息傳遞給 GetFlights.jsp。否則,讓用戶返回到 Welcome.jsp 頁面,以便選擇其他航班。
    • 如果有航班,那么 DerbyDatabase 類將從數(shù)據(jù)庫檢索到的航班信息放入到名為 FlightsBean 的 JavaBean 中。
  • 通過更新 Flight History 預(yù)訂用戶的航班
    • 這里使用的 JSP 是 BookFlights.jsp 和 GoodBye.jsp。BookFlights.jsp 請(qǐng)求用戶對(duì)他們預(yù)訂的航班作最后的確認(rèn)。GoodBye.jsp 顯示用戶通過 Derby Airlines 預(yù)訂的所有航班。
    • UpdateHistoryServlet 以用戶名和用戶剛預(yù)訂的航班更新 APP.FlightHistory 表。然后請(qǐng)求被重定向到 GoodBye.jsp。
  • 用戶退出
    • 應(yīng)用程序的最后階段是退出應(yīng)用程序,或者預(yù)訂其他航班。這里使用的 JSP 是 LoggedOut.jsp,或者,如果用戶還想預(yù)訂其他的航班,則使用 Welcome.jsp。
    • 如果用戶選擇退出,則從 Session 對(duì)象中刪除用戶 ID。因此,當(dāng)該用戶下一次重返站點(diǎn)時(shí),雖然保留了一個(gè)持久 cookie,但用戶 ID 不在 Session 對(duì)象中,因此用戶必須再次登錄。

下面的圖生動(dòng)地展示了這一流程。


圖 2. 示例應(yīng)用程序的流程











從 WAR 創(chuàng)建 Web 項(xiàng)目

為了理解如何使用隨 WTP 附帶的不同工具以及 Derby 插件,請(qǐng)將應(yīng)用程序作為 WAR 文件導(dǎo)入,WAR 是 Web 應(yīng)用程序的標(biāo)準(zhǔn)打包單元,其文件格式為 JAR。

構(gòu)建任何使用 JSP 或 Servlet 的 Web 應(yīng)用程序的第一步是創(chuàng)建一個(gè)動(dòng)態(tài) Web 應(yīng)用程序。您可以使用 WTP 的一組工具創(chuàng)建這樣一個(gè)動(dòng)態(tài) Web 應(yīng)用程序,它將為 J2EE Web 應(yīng)用程序自動(dòng)創(chuàng)建適當(dāng)?shù)哪夸浗Y(jié)構(gòu)。將 WAR 文件導(dǎo)入到 Project Explorer 視圖的 Dynamic Web Project 文件夾中,以便創(chuàng)建一個(gè)新的 Web 項(xiàng)目。

啟動(dòng) Eclipse,遵循以下步驟導(dǎo)入 WAR 文件,以創(chuàng)建一個(gè)新的動(dòng)態(tài) Web 項(xiàng)目:

  1. 打開 J2EE 透視圖。
  2. 在 Project Explorer 視圖中,右鍵單擊 Dynamic Web Projects 文件夾。
  3. 選擇 Import,然后在 Import 窗口中,選擇 WAR file 并單擊 Next
  4. 在 WAR Import 窗口中,瀏覽到早先下載的 LowFareAir.war 文件(見前面的 軟件需求)。將項(xiàng)目命名為 LowFareAir,并確保 Target server 是 Apache Tomcat V5.0(這是您早先作了配置的,見前面的 軟件配置)。單擊 Finish

圖 3 展示了這個(gè)過程的最后一步。


圖 3. 導(dǎo)入 WAR 文件以創(chuàng)建動(dòng)態(tài) Web 項(xiàng)目

您還需要導(dǎo)入三個(gè)上述 WAR 文件中沒有的 JAR 文件:jstl.jar 和早先下載的 Jakarta taglibs 包中的 standard.jar,以及 Derby 核心插件中的 derbyclient.jar 文件。通常,一個(gè)完整的 WAR 文件會(huì)包括這些 JAR 文件,但出于演示的目的,您應(yīng)該知道如何將它們導(dǎo)入到動(dòng)態(tài) Web 項(xiàng)目中。

為了獲得 Jakarta 包中的這幾個(gè) JAR 文件,請(qǐng)解壓 jakarta-taglibs-standard-1.1.2.zip 文件。jstl.jar 和 standard.jar 文件在新創(chuàng)建的 jakarta-taglibs-standard-1.1.2/lib 目錄中。為了導(dǎo)入這幾個(gè) JAR 文件:

  1. 打開 Dynamic Web Projects 文件夾。這時(shí)將出現(xiàn)剛才導(dǎo)入的 LowFareAir 項(xiàng)目。展開這個(gè)文件夾,然后展開 WebContent 文件夾。
  2. 右鍵單擊 WebContent/WEB-INF/lib 文件夾并選擇 Import。在 Import 窗口中,選擇 File System,然后單擊 Next。
  3. 瀏覽至子目錄 jakarta-taglibs-standard-1.1.2/lib,您曾經(jīng)將 taglibs 解壓至該目錄,然后選擇 jstl.jar 和 standard.jar。確保導(dǎo)入到 LowFareAir/WebContent/WEB-INF/lib 目錄。然后單擊 Finish。

 

現(xiàn)在需要將 derbyclient.jar 文件添加到 Web 應(yīng)用程序可用的庫中。您的 Web 應(yīng)用程序?qū)⑹褂?derbyclient.jar 中的 JDBC 來建立到數(shù)據(jù)庫的連接。

為了導(dǎo)入 derbyclient.jar:

  1. 右鍵單擊 WebContent/WEB-INF/lib 文件夾并選擇 Import。在 Import 窗口中,選擇 File System,然后單擊 Next。
  2. 瀏覽至 Eclipse 主目錄下的插件目錄,然后打開 org.apache.derby.core_10.1.1 目錄。選擇 derbyclient.jar。確保導(dǎo)入到 LowFareAir/WebContent/WEB-INF/lib 目錄。然后單擊 Finish。

這樣便完成了 Web 組件的導(dǎo)入,包括 Java 源文件和用于應(yīng)用程序的所有庫。接下來,導(dǎo)入裝有示例數(shù)據(jù)的 Derby 數(shù)據(jù)庫 airlinesDB。






配置數(shù)據(jù)層

為了配置數(shù)據(jù)層以及應(yīng)用程序用于訪問數(shù)據(jù)庫的工具:

  1. 將 Apache Derby Nature 添加到 LowFareAir 項(xiàng)目中。
  2. 將 LowFareAirData.zip 文件導(dǎo)入到項(xiàng)目中。該 zip 文件包含 airlinesDB Derby 數(shù)據(jù)庫,其中包含所有用于應(yīng)用程序的數(shù)據(jù)以及一些示例 SQL 腳本。
  3. 配置 Web 應(yīng)用程序部署描述符 web.xml,以包含一個(gè)指向 airlinesDB 數(shù)據(jù)庫的數(shù)據(jù)源。
  4. 將 Derby 屬性 derby.system.home 設(shè)置為指向 airlinesDB 數(shù)據(jù)庫的完整路徑。通過設(shè)置這個(gè)屬性,在 JDBC 連接 URL 中所有對(duì) airlinesDB 數(shù)據(jù)庫的引用都只需引用“airlinesDB”,而不必引用完整的文件系統(tǒng)路徑。

 

添加 Apache Derby 特性

該 Web 應(yīng)用程序使用一個(gè) Derby 數(shù)據(jù)庫來為虛擬的 LowFareAir 航空公司存儲(chǔ)和查詢航班信息。在 Eclipse 中訪問和使用 Derby 數(shù)據(jù)庫的一種簡便方法是通過 Derby 插件。

Derby 插件允許添加 Derby 特性到任何 Eclipse 項(xiàng)目中。將一種特性添加到一個(gè)項(xiàng)目(包括動(dòng)態(tài) Web 項(xiàng)目),意味著該項(xiàng)目將“繼承”某些功能和行為。而添加 Derby 特性則意味著將與 Derby 捆綁的 Derby 數(shù)據(jù)庫 JAR 文件和命令行工具添加到 Eclipse 環(huán)境中。

Project Explorer 視圖現(xiàn)在將顯示剛才創(chuàng)建的 LowFareAir 項(xiàng)目。

為了添加 Derby 特性到 LowFareAir 項(xiàng)目中,在它上面單擊右鍵并選擇菜單項(xiàng) Apache Derby > Add Apache Derby nature。

導(dǎo)入 LowFareAirData.zip

源代碼中包括了 airlinesDB,這是用于 Web 應(yīng)用程序的示例數(shù)據(jù)庫。這個(gè)數(shù)據(jù)庫和其他一些示例 SQL 都需要導(dǎo)入到 LowFareAir 項(xiàng)目中。為此:

  1. 展開 Dynamic Web Projects 文件夾。右鍵單擊 LowFareAir 文件夾并選擇 Import。在 Import 窗口中,選擇 Archive file,然后單擊 Next。
  2. 瀏覽至 LowFareAirData.zip,確保選擇了左框中的 / 目錄。這里包括 data 和 sql 文件夾。選擇 LowFareAir 作為 Into 文件夾的名稱。然后單擊 Finish。
  3. 如果導(dǎo)入成功,LowFareAir 文件夾應(yīng)該包含兩個(gè)新的子文件夾:data 和 sql。data 文件夾將包含 airlinesDB 目錄(數(shù)據(jù)庫)。
  4. sql 目錄包含三個(gè) SQL 文件,分別是 airlinesDB.sql、flights.sql 和 flighthistory_users.sql。

 

現(xiàn)在 Web 應(yīng)用程序所需的所有文件都已導(dǎo)入完畢,LowFareAir 項(xiàng)目的結(jié)構(gòu)現(xiàn)在看上去應(yīng)該如圖 4 所示。


圖 4. LowFareAir 項(xiàng)目的 Project Explorer 視圖

用 Derby 數(shù)據(jù)源配置 web.xml

web.xml 文件包含關(guān)于使用 Derby airlinesDB 數(shù)據(jù)庫作為數(shù)據(jù)源的一個(gè)數(shù)據(jù)源條目。并不是每個(gè)連接到 Derby 數(shù)據(jù)庫的 Web 應(yīng)用程序都需要如此。但是為了演示的目的,這個(gè)應(yīng)用程序?yàn)榈谝粋€(gè) JSP 頁面使用一個(gè)數(shù)據(jù)源。其他 JSP 不使用這個(gè)數(shù)據(jù)源,而 Servlet 使用一個(gè)標(biāo)準(zhǔn)的 Java 類,該類使用 JDBC 連接到數(shù)據(jù)庫。

為了確定 airlinesDB 在文件系統(tǒng)上的位置,右鍵單擊 LowFareAir 項(xiàng)目的 data 目錄下的 airlinesDB 文件夾,選擇 Properties。Properties 窗口顯示一個(gè) Location 字段,其中有指向 airlinesDB 目錄的完整文件系統(tǒng)路徑。復(fù)制這個(gè)字符串,以便在下一步中使用。例如,這個(gè)路徑可能類似于 C:\eclipse\workspace\LowFareAir\data\airlinesDB。

打開 web.xml(在 WebContent/WEB-INF 目錄下),在以 Source 模式查看時(shí)瀏覽至下面這一段(為了提高可讀性,param-value 部分中的條目加入了換行符,但是 URL 應(yīng)該是連續(xù)的一行):


清單 1. Web.xml context-param 部分
                                    <context-param>                                    <param-name>javax.servlet.jsp.jstl.sql.dataSource</param-name>                                    <param-value>                                    jdbc:derby://localhost:1527/C:\eclipse\workspace\LowFareAir\data\ /                                    airlinesDB;user=a;password=b;,                                    org.apache.derby.jdbc.ClientDriver                                    </param-value>                                    </context-param>

使用剛才復(fù)制的 airlinesDB 數(shù)據(jù)庫的完整路徑,將 <param-value> 部分中的值改為您環(huán)境中的數(shù)據(jù)庫 URL。如果這個(gè)路徑不正確,應(yīng)用程序的第一個(gè)頁面(Welcome.jsp)將失敗。而且,在運(yùn)行 Welcome.jsp 之前,需要啟動(dòng)網(wǎng)絡(luò)服務(wù)器,因?yàn)榍懊骘@示的 URL 嘗試使用 Derby Client 驅(qū)動(dòng)程序訪問網(wǎng)絡(luò)服務(wù)器。

為項(xiàng)目設(shè)置 derby.system.home

在 Eclipse 中配置 Derby 數(shù)據(jù)庫環(huán)境的下一步是編輯名為 derby.system.home 的 Derby 系統(tǒng)屬性,使之指向 airlinesDB 數(shù)據(jù)庫的位置。這樣您便可以使用 Derby 插件連接到 airlinesDB,而不必指定到數(shù)據(jù)庫的完整文件系統(tǒng)路徑。在數(shù)據(jù)庫連接 URL 中只需列出名稱 airlinesDB。

使用之前復(fù)制的 airlinesDB 目錄的路徑設(shè)置 derby.system.home,只需做少量修改。

  1. 右鍵單擊 LowFareAir 項(xiàng)目并選擇 Properties。
  2. 在 Properties 窗口的左側(cè)(當(dāng)前它提示 PropertyDialog.propertyMessage —— 看來是一個(gè) bug)選擇 Apache Derby。
  3. 在右側(cè)是 Apache Derby 屬性,您可以更改該屬性。名為 derby.system.home 的 Derby System 屬性當(dāng)前被設(shè)為默認(rèn)值(.)。將其改為指向 airlinesDB 目錄所在目錄的完整路徑。注意:您也可以在 port 屬性中修改網(wǎng)絡(luò)服務(wù)器所偵聽的端口。
    編輯 derby.system.home 屬性的值,將其設(shè)置為 data 目錄的完整路徑。粘貼您之前復(fù)制的字符串,然后去掉后面的 \airlinesDB。所以,derby.system.home 屬性將成為:C:\eclipse\workspace\LowFareAir\data。注意:不要輸入數(shù)據(jù)庫目錄本身的名稱 —— 它應(yīng)該是數(shù)據(jù)庫目錄所在的目錄,在這里就是 data 目錄,而不是 airlinesDB 目錄本身。
  4. 最后單擊 OK 保存對(duì)項(xiàng)目的設(shè)置。

接下來您將啟動(dòng) Derby Network Server,建立到 airlinesDB 數(shù)據(jù)庫的連接,并使用隨 Derby 插件附帶的 ij 工具發(fā)出 SQL。

啟動(dòng) Derby 網(wǎng)絡(luò)服務(wù)器并運(yùn)行 ij

由于您要對(duì) airlinesDB 中的表運(yùn)行一些查詢,所以有必要知道有哪些表,這些表是如何定義的。下面就顯示了這些表。SQL 文件 airlinesDB.sql 用于創(chuàng)建數(shù)據(jù)庫。不要再次運(yùn)行 airlinesDB.sql,除非您刪除了舊的數(shù)據(jù)庫,并希望在一個(gè)新的數(shù)據(jù)庫中重新創(chuàng)建所有的表。


清單 2. 在 airlinesDB 數(shù)據(jù)庫中創(chuàng)建表的語句
                                    CREATE TABLE APP.CITIES                                    (                                    CITY_ID          INTEGER NOT NULL constraint cities_pk primary key,                                    CITY_NAME        VARCHAR(24) NOT NULL,                                    COUNTRY          VARCHAR(26) NOT NULL,                                    AIRPORT          VARCHAR(26),                                    LANGUAGE         VARCHAR(16),                                    COUNTRY_ISO_CODE CHAR(2)                                    );                                    CREATE TABLE APP.FLIGHTS                                    (                                    FLIGHT_ID      CHAR(6) NOT NULL,                                    SEGMENT_NUMBER INTEGER NOT NULL,                                    ORIG_AIRPORT   CHAR(3),                                    DEPART_TIME    TIME,                                    DEST_AIRPORT   CHAR(3),                                    ARRIVE_TIME    TIME,                                    MEAL           CHAR(1) CONSTRAINT MEAL_CONSTRAINT                                    CHECK (meal IN (‘B‘, ‘L‘, ‘D‘, ‘S‘)),                                    FLYING_TIME    DOUBLE PRECISION,                                    MILES          INTEGER,                                    AIRCRAFT       VARCHAR(6),                                    CONSTRAINT FLIGHTS_PK Primary Key (FLIGHT_ID, SEGMENT_NUMBER)                                    );                                    CREATE TABLE APP.FLIGHTAVAILABILITY                                    (                                    FLIGHT_ID              CHAR(6) NOT NULL ,                                    SEGMENT_NUMBER         INTEGER NOT NULL ,                                    FLIGHT_DATE            DATE NOT NULL ,                                    ECONOMY_SEATS_TAKEN    INTEGER DEFAULT 0,                                    BUSINESS_SEATS_TAKEN   INTEGER DEFAULT 0,                                    FIRSTCLASS_SEATS_TAKEN INTEGER DEFAULT 0,                                    CONSTRAINT FLIGHTAVAIL_PK Primary Key                                    (FLIGHT_ID, SEGMENT_NUMBER, FLIGHT_DATE),                                    CONSTRAINT FLIGHTS_FK2 Foreign Key (FLIGHT_ID, SEGMENT_NUMBER)                                    REFERENCES FLIGHTS (FLIGHT_ID, SEGMENT_NUMBER)                                    );                                    CREATE TABLE APP.FLIGHTHISTORY                                    (                                    ID             INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,                                    USERNAME       VARCHAR(26) NOT NULL,                                    FLIGHT_ID      CHAR(6) NOT NULL,                                    ORIG_AIRPORT   CHAR(3) NOT NULL,                                    DEST_AIRPORT   CHAR(3) NOT NULL,                                    BEGIN_DATE     CHAR(12),                                    CLASS          CHAR(12)                                    );                                    CREATE TABLE APP.USERS                                    (                                    ID             INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,                                    USERNAME       VARCHAR(40) NOT NULL,                                    PASSWORD       VARCHAR(20)                                    );

現(xiàn)在右鍵單擊 LowFareAir 項(xiàng)目并選擇 Apache Derby > Start Derby Network Server,從而啟動(dòng) Derby 網(wǎng)絡(luò)服務(wù)器??刂婆_(tái)視圖應(yīng)該會(huì)表示,服務(wù)器準(zhǔn)備在 Derby 屬性 Network Server 設(shè)置中指定的端口上接受連接。打開 sql 文件夾并右鍵單擊 flights.sql 文件。選擇 Apache Derby > Run SQL Script using ‘ij‘。

控制臺(tái)窗口將顯示 flights.sql 文件中包含的三條 SQL 語句的輸出。 如果沒有成功建立連接,那么檢查網(wǎng)絡(luò)服務(wù)器是否已經(jīng)啟動(dòng),以及 derby.system.home 是否被設(shè)為 LowFareAir 文件夾下 data 目錄的完整路徑。





WTP Data 工具 —— 一種替代方案

WTP 有一組豐富的數(shù)據(jù)庫工具,允許用戶連接到 Derby、DB2、Informix、MySql、Oracle、SQL Server 和 Sybase 數(shù)據(jù)庫,瀏覽這些數(shù)據(jù)庫,以及對(duì)這些數(shù)據(jù)庫發(fā)出 SQL。在本節(jié)中,您將連接到使用 Derby Network Client 驅(qū)動(dòng)程序的 Derby Network Server,并學(xué)習(xí)如何使用 WTP 的一些工具作為使用 Derby 插件的替代方案。

在 J2EE 透視圖中,選擇 Window > Show View > Other。在 Show View 窗口中,選擇 Data > Database Explorer 然后單擊 OK。Database Explorer 視圖將出現(xiàn)在工作區(qū)的右下端。在此視圖中單擊右鍵,并選擇 New Connection。

這時(shí)將出現(xiàn) New Connection 向?qū)АH∠麑?duì) Use default naming convention 復(fù)選框的選擇,并將連接命名為 Derby 10.1。在 Select a database manager 區(qū)域,展開樹中的 Derby 項(xiàng)。注意,它列出 10.0 版的數(shù)據(jù)庫系統(tǒng)。

WTP 0.7 只直接支持 Derby 10.0,但是,最新版本的 Derby 是 10.1 版,而且您將在這里與 Database Explorer 一起使用的 Derby JAR 文件是 10.1 版。在 10.1 版的 Derby 中,建議采用一種新的開放源碼客戶機(jī)驅(qū)動(dòng)程序 —— derbyclient.jar —— 來連接到網(wǎng)絡(luò)服務(wù)器。

下圖展示了在我的環(huán)境中每個(gè)字段的值。下面的表還列出了示例設(shè)置。


圖 5. WTP Database Explorer 的 New Connection 向?qū)?/b>

表 1. 使用 Derby Client Driver 的 Derby 10.1 連接的示例值
參數(shù)
Connection Name Derby 10.1
Database manager Derby 10.0
JDBC driver Other
Database C:\eclipse\workspace\LowFareAir\data\airlinesDB
JDBC driver class org.apache.derby.jdbc.ClientDriver
Class location C:\eclipse\plugins\org.apache.derby.core_10.1.1\derbyclient.jar
Connection URL jdbc:derby://localhost:1527/C:\eclipse\workspace\LowFareAir\data\airlinesDB
User ID slc (any non-empty value)
Password slc (any non-empty value)

對(duì) Derby 數(shù)據(jù)庫是可以配置認(rèn)證的,但是這里還沒有為 airlinesDB 數(shù)據(jù)庫設(shè)置認(rèn)證。使用任意(非空)值作為用戶 ID 和密碼,并單擊 Test Connection 按鈕。如果網(wǎng)絡(luò)服務(wù)器在端口 1527 上運(yùn)行,那么測試應(yīng)該可以成功。否則,確保網(wǎng)絡(luò)服務(wù)器在連接 URL 指定的端口上運(yùn)行,并確保所有的值都適合您的環(huán)境。

由于網(wǎng)絡(luò)服務(wù)器是用來連接到 airlinesDB 數(shù)據(jù)庫的,因此可以由多個(gè) JVM 訪問它。這意味著 ij、Database Explorer 和 Eclipse 外部的客戶機(jī)應(yīng)用程序都可以連接和查詢?cè)摂?shù)據(jù)庫中的表。

測試連接成功之后,單擊 Next 按鈕。

Specify Filter 窗口中,取消對(duì) Disable filter 復(fù)選框的選擇,選擇 Selection 并選擇 APP 模式。然后單擊 Finish。


圖 6. 為 Derby 10.1 連接指定過濾器

現(xiàn)在,Database Explorer 視圖顯示到 airlinesDB 數(shù)據(jù)庫的連接。展開樹,瀏覽至 APP 模式的 Tables 文件夾下的 FLIGHTS 表。右鍵單擊 FLIGHTS 表,并選擇 Data > Sample Contents。


圖 7. Database Explorer 中的示例連接

現(xiàn)在將出現(xiàn) Data Output 視圖,其中包含 FLIGHTS 表中的行。


圖 8. Data Output 視圖

Database Explorer 視圖的另一個(gè)特性是可以插入、刪除和更新表中的行。Table Editor 提供了修改表中數(shù)據(jù)的能力。如果您想添加另一行到 FLIGHTS 表中,在 Database Explorer 視圖中右鍵單擊這個(gè)表,選擇 Data > Open。輸入一個(gè)新的行,在每個(gè)列中提供如下所示的值。注意 FLIGHTS 選項(xiàng)卡上單詞 FLIGHTS 之前的那個(gè)星號(hào)。這表明,自上次保存以來,編輯器已經(jīng)被修改。


圖 9. Table Editor

為了插入行到表中,選擇 File > Save 或使用快捷鍵 Ctrl + S 保存編輯器。Data Output 視圖的 Messages 選項(xiàng)卡顯示數(shù)據(jù)插入成功。


圖 10. 成功地插入一行到 FLIGHTS 表中

Database Explorer 視圖的其他特性包括抽取和下載表的能力、打開 SQL Editor 以發(fā)出即席 SQL,以及 Generate DDL 選項(xiàng),該選項(xiàng)在生成用于創(chuàng)建整個(gè)數(shù)據(jù)庫模式或模式的一個(gè)子集的 SQL 腳本時(shí)十分有用。您可以通過在模式對(duì)象(表、視圖、索引或模式)上單擊右鍵自己探索這些選項(xiàng),看看對(duì)于特定的對(duì)象有哪些可用的選項(xiàng)。





探索視圖層和 JSP

現(xiàn)在可以開始查看應(yīng)用程序中的 JSP。參考 圖 2 中的應(yīng)用程序流程,第一個(gè) JSP 頁面是 Welcome.jsp。在 Project Explorer 中,打開 WebContent 文件夾下的 Welcome.jsp 文件。下面的小節(jié)中將展示這個(gè)頁面的代碼。注意:有些代碼清單有反斜杠字符“\”,這表示代碼行是連續(xù)的,但為了可讀性,這里對(duì)其格式作了調(diào)整。


清單 3. 在 Welcome.jsp 中導(dǎo)入 Core 和 SQL 標(biāo)記庫
                                    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>                                    <%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>

前兩行包括可用于 JSP 頁面的 taglib 指令,這樣便可以使用 core 和 SQL JSTL 標(biāo)記庫。

接下來這一段使用 core 標(biāo)記庫來測試在用戶瀏覽器中是否設(shè)置了 cookie。如果沒有 cookie,那么將 JSP 頁面重定向到 Register.jsp。如果至少有一個(gè) cookie,那么檢查是否設(shè)置了名為 derbyCookie 的 cookie。如果存在 derbyCookie,那么接下來的測試是檢查 Session 對(duì)象是否包含一個(gè)用戶 ID。如果沒有包括用戶 ID,那么用戶進(jìn)入 Login.jsp 頁面,以登錄到應(yīng)用程序。

如果用戶在 Session 對(duì)象中有用戶 ID,那么用戶可以繼續(xù),處理仍停留在 Welcome.jsp 頁面。


清單 4. 測試 Welcome.jsp 中是否設(shè)置了 cookie
                                    <HTML>                                    <HEAD>                                    <TITLE>Derby Airlines</TITLE>                                    </HEAD>                                    <BODY>                                    <c:choose>                                    <c:when test="${empty cookie}">                                    <jsp:forward page="Register.jsp" />                                    </c:when>                                    <c:otherwise>                                    <!--  if the derbyCookie has been set but the username is not in                                     the session object -->                                    <c:forEach var="cookieVal" items="${cookie}">                                    <c:if test="${cookieVal.key == ‘derbyCookie‘}">                                    <c:if test="${empty sessionScope.username}">                                    <jsp:forward page="Login.jsp" />                                    </c:if>                                    </c:if>                                    </c:forEach>                                    </c:otherwise>                                    </c:choose>

下面的代碼檢查當(dāng) post 該頁面時(shí),參數(shù) nodirectflights 是否被設(shè)為 true。如果繼續(xù)查看該代碼,那么可以發(fā)現(xiàn),表單的動(dòng)作是 post to the CheckFlightsServlet。根據(jù)用戶選擇的出發(fā)地和目的地,如果 CheckFlightsServlet 沒有任何直達(dá)航班,則參數(shù) nodirectflights 被設(shè)為 true,用戶返回該頁面,這個(gè)代碼片段將顯示關(guān)于沒有直達(dá)航班的消息。


清單 5. 在 Welcome.jsp 中顯示關(guān)于是否有直達(dá)航班的消息
                                    <c:if test="${nodirectflights == ‘true‘}" >                                    <p>                                    There were no direct flights between <font color="blue" size="5">                                    ${cityNameFrom}</font> and <font color="blue" size="5">                                    ${cityNameTo}</font>. <br>                                    Please select another flight.                                    </p>                                    </c:if>                                    

您可以使用 JSTL core out 標(biāo)記來顯示傳遞給 JSP 的會(huì)話對(duì)象或請(qǐng)求對(duì)象中的參數(shù)。登錄成功之后,用戶 ID 被放入 Session 對(duì)象,并且在用戶訪問 Welcome.jsp 頁面時(shí)顯示在該頁面上。而且,注意用于包括 CalendarServlet 的 jsp:include 標(biāo)記,CalendarServlet 用于顯示當(dāng)前的月、日和年,并且有一個(gè)用于選擇出發(fā)日期的下拉框。


清單 6. 成功登錄之后
                                    <H3>                                    Welcome to Derby Air, <c:out value="${username}" />!</H3>                                    <p>                                    Please proceed to select a flight.                                    </p>                                    <form action="CheckFlightsServlet" method="post">                                    <table width="50%">                                    <tr>                                    <td valign="top">                                    <b>Departure Date:</b><br>                                    <jsp:include page="/CalendarServlet">                                    <jsp:param name="type" value="orig" />                                    </jsp:include>                                    </td>                                    

下面這段代碼使用 JSTL SQL 庫。在像下面這樣使用 sql:query 標(biāo)記之前,您已經(jīng)在應(yīng)用程序的 web.xml 文件中設(shè)置了 DataSource。以后將討論那個(gè)條目,但是現(xiàn)在請(qǐng)注意這個(gè)標(biāo)記使用起來有多么容易。代碼中發(fā)出對(duì) CITIES 表的查詢,以返回 APP.CITIES 表的 city_name、countryairport 列中所包含的值。查詢的結(jié)果放在一個(gè)名為 cities 的變量中,這是一個(gè) javax.servlet.jsp.jstl.sql.Result 對(duì)象。Result 對(duì)象有一個(gè)名為 getRows() 的方法,該方法返回對(duì)象中包含的所有行。這些行作為一個(gè) java.util.SortedMap 對(duì)象數(shù)組返回。


清單 7. 使用 SQL 標(biāo)記庫
                                    <sql:query var="cities">                                    SELECT CITY_NAME, COUNTRY, AIRPORT FROM APP.CITIES ORDER BY                                     CITY_NAME, COUNTRY                                    </sql:query>

下面展示了通過 forEach 標(biāo)記對(duì) cities Result 對(duì)象中包含的行的迭代。在對(duì)這個(gè)數(shù)組的每一次迭代中,變量 city 包含一個(gè) SortedMap 對(duì)象。Expression Language 允許通過引用表示數(shù)據(jù)庫中一行的特定 SortedMap 對(duì)象中的列名,來訪問每個(gè)行中的每個(gè)列。


清單 8. 輸出 SQL 查詢的結(jié)果
                                    <td>                                    <b>Origin:</b><br>                                    <select name="from" size="4">                                    <c:forEach var="city" items="${cities.rows}">                                    <option value="${city.airport}"> ${city.city_name}, ${city.country}                                    </option>                                    </c:forEach>                                    </select>                                    <br><br>                                    </td>                                    </tr>

這里不顯示該頁面的其他部分。這段代碼像前面生成 Origin 一樣輸出 Destination 下拉框,然后提供一個(gè)按鈕,以便用戶提交查詢來查看出發(fā)地(Origin)和目的地(Destination)之間的航班。





考察控制流并運(yùn)行應(yīng)用程序

在運(yùn)行 LowFare Air 之前,如果 Derby Network Server 還沒有運(yùn)行,那么需要啟動(dòng)它。右鍵單擊 LowFareAir 文件夾,然后選擇 Apache Derby > Start Derby Network Server。

現(xiàn)在右鍵單擊 Project Explorer 視圖中的 Welcome.jsp 文件。選擇 Run As > Run On Server。


圖 11. 在 Tomcat Server 上運(yùn)行 Welcome.jsp

這樣將彈出 Run on Server 向?qū)?。按照下面的步驟完成該向?qū)В?

  1. 選擇 localhost 作為 Server 的主機(jī)名。對(duì)于服務(wù)器類型,展開 Apache 文件夾并選擇 Tomcat v5.0。 選中 Set server as project default 復(fù)選框。單擊 Next 按鈕。
  2. 在 Add and Remove Projects 窗口中,確信 LowFareAir 項(xiàng)目列出在 Configured Projects 區(qū)域中。如果 LowFareAir 項(xiàng)目沒有出現(xiàn)在那里,而是出現(xiàn)在 Available Projects 類別中,那么將它轉(zhuǎn)移到 Configured Projects 類別中。單擊 Finish

 

這將啟動(dòng)外部的 Tomcat 服務(wù)器,并打開一個(gè)瀏覽器窗口,以便在這個(gè)窗口運(yùn)行 JSP。在 Windows 中,默認(rèn)情況是在 Eclipse 中打開一個(gè)內(nèi)部瀏覽器。而在 Linux 中,默認(rèn)情況是打開外部瀏覽器。

為了配置外部瀏覽器的啟動(dòng):

  1. 選擇 Window > Preferences。
  2. 選擇 General 樹項(xiàng),然后選擇 Web Browser。
  3. 選擇 Use external Web browser 按鈕,然后從列表中列出的可用瀏覽器中選擇一個(gè)。
  4. 單擊 OK 設(shè)置首選項(xiàng)。

 

用不同的瀏覽器檢查 Web 頁面總是一個(gè)很好的習(xí)慣。不同的瀏覽器在呈現(xiàn)一些 HTML 元素以及處理 cookie 的默認(rèn)方式上會(huì)有一些差異。

如前所述,第一次打開 Welcome.jsp 時(shí),會(huì)轉(zhuǎn)入 Register.jsp 頁面。 由于還沒有設(shè)置 derbyCookie,所以 Welcome.jsp 會(huì)將您帶到 Register.jsp,以便創(chuàng)建一個(gè)用戶 ID 和密碼。見圖 12。


圖 12. 帶新用戶 ID 條目的 Register.jsp

當(dāng)您輸入一個(gè)用戶 ID 和密碼,并單擊 Register New User 按鈕時(shí),這些值被傳遞給 LoginServlet 類?,F(xiàn)在打開這個(gè) Java 類,這個(gè)類位于 LowFareAir > Java Resources > JavaSource > com.ibm.sample 文件夾和包結(jié)構(gòu)下。

doPost 方法首先解析傳入的參數(shù),包括您剛才在 Register.jsp 中設(shè)置的用戶 ID 和密碼。


清單 9. LoginServlet 類的 doPost 方法
                                    protected void doPost(HttpServletRequest request,                                    HttpServletResponse response) throws ServletException, IOException                                    {                                    String user = request.getParameter("username");                                    String password = request.getParameter("password");                                    // Register.jsp set the parameter newuser                                    String newUser = request.getParameter("newuser");                                    String loggedOut = request.getParameter("loggedOut");

然后,它通過調(diào)用 DerbyDatabase 類的 getConnInstance() 方法連接到 Derby 數(shù)據(jù)庫。getConnInstance 方法返回一個(gè)到數(shù)據(jù)庫的單態(tài) java.sql.Connection。


清單 10. 將 conn 變量設(shè)置為 DerbyDatabase 類的單態(tài) Connection 對(duì)象
                                    Connection conn = DerbyDatabase.getConnInstance();

下面一段代碼確定用戶是否為新用戶,如果用戶 ID 已存在,那么從數(shù)據(jù)庫中選擇用戶 ID,否則,將用戶 ID 添加到數(shù)據(jù)庫。


清單 11. 在 LoginServlet 類中處理新用戶
                                    // the user is not new, so look up the username and password                                    // in the APP.USERS table                                    if (newUser == null || newUser.equals(""))                                    {                                    sql = "select * from APP.USERS where username = ‘" + user                                    + "‘ and password = ‘" + password + "‘";                                    String[] loginResults = DerbyDatabase.runQuery(conn, sql);                                    // if the query was successful one row should be returned                                    if (loginResults.length == 1)                                    {                                    validUser = true;                                    }                                    }                                    // the user is new, insert the username and password into                                    // the APP.USERS table                                    else                                    {                                    sql = "insert into APP.USERS (username, password) values " + "(‘"                                    + user + "‘, ‘" + password + "‘)";                                    int numRows = DerbyDatabase.executeUpdate(conn, sql);                                    if (numRows == 1)                                    {                                    validUser = true;                                    }                                    }                                    

為驗(yàn)證用戶 ID Susan 是否被添加到 APP.USERS 表中,打開 Derby 插件中的 SQL 工具 ij,查詢 APP.USERS 表。

為了打開 ij,右鍵單擊 LowFareAir 文件夾,然后選擇 Apache Derby > ij (Interactive SQL)。 從 ij 中發(fā)出 connect 語句連接到 airlinesDB 數(shù)據(jù)庫,并運(yùn)行查詢 select * from APP.USERS;,看看您輸入到瀏覽器中的用戶 ID 是否出現(xiàn)在這里。在這個(gè)例子中,用戶 ID 是 Susan。

注意:對(duì)于在控制臺(tái)視圖中光標(biāo)的位置,3.1 版的 Eclipse 與之前的版本相比有些不同。光標(biāo)總是停留在一行的開始處。雖然看上去有些古怪,但是如果您開始在 ij 提示符下輸入內(nèi)容,光標(biāo)又會(huì)回到適當(dāng)?shù)奈恢?,也就是?ij 中的 ‘j‘ 之后。


清單 12. 連接到 airlinesDB 數(shù)據(jù)庫
                                    connect ‘jdbc:derby://localhost:1527/airlinesDB‘;                                    select * from APP.USERS;

ij 的輸出如下所示。


圖 13. 來自 APP.USERS 表的 ij 結(jié)果

Register.jsp 正確地傳遞這些值,而 LoginServlet.java 則將用戶 ID 和密碼正確地插入到表中。這樣,用戶 ID ‘slc‘ 和密碼 ‘slc‘ 便已經(jīng)在表中。

LoginServlet.java 中的其他代碼處理不正確的用戶 ID 和密碼,然后,如果一切沒問題,則將結(jié)果送到 Welcome.jsp。下圖展示了 Origin 為 Albuquerque、Destination 為 Los Angeles 時(shí)的 Welcome.jsp。注意,用戶 ID 被從 LoginServlet.java 傳遞到 Welcome.jsp,以便顯示。


圖 14. 成功登錄之后的 Welcome.jsp

Welcome.jsp post 到 CheckFlightsServlet.java。打開 CheckFlightsServlet.java。關(guān)于這個(gè) servlet 要注意的一點(diǎn)是,在解析傳入的參數(shù)之后,它調(diào)用 DerbyDatabase 方法 origDestFlightList()。這個(gè)方法返回一個(gè) FlightsBean 對(duì)象數(shù)組。


清單 13. CheckFlightsServlet 類
                                    Connection conn = DerbyDatabase.getConnInstance();                                    FlightsBean[] fromToFlights =                                     DerbyDatabase.origDestFlightList(conn, from, to);

當(dāng) FlightsBean 數(shù)組填充了內(nèi)容之后,CheckFlightsServlet 將結(jié)果放入變量名為 fromToFlights 的會(huì)話對(duì)象。


清單 14. 將 FlightsBean 數(shù)組放入會(huì)話對(duì)象
                                    request.getSession().setAttribute("fromToFlights", fromToFlights);

現(xiàn)在打開 DerbyDatabase.java 類,看看這個(gè)方法做些什么。為便于查看,其中部分代碼的格式稍微作了調(diào)整。


清單 15. 查看 DerbyDatabase 類中的 origDestFlightList 方法
                                    public static FlightsBean[] origDestFlightList(Connection conn,                                     String origAirport, String destAirport)                                    {                                    String query = "select flight_id, segment_number, orig_airport, " +                                    "depart_time, dest_airport, arrive_time, meal, flying_time, miles," +                                    "aircraft from app.flights where ORIG_AIRPORT = ? AND " +                                    "DEST_AIRPORT = ?";                                    List list = Collections.synchronizedList(new ArrayList(10));                                    try                                    {                                    PreparedStatement prepStmt = conn.prepareStatement(query);                                    prepStmt.setString(1, origAirport);                                    prepStmt.setString(2, destAirport);                                    ResultSet results = prepStmt.executeQuery();                                    while(results.next())                                    {                                    String flightId = results.getString(1);                                    String segmentNumber = results.getString(2);                                    String startAirport = results.getString(3);                                    String departTime = results.getString(4);                                    String endAirport = results.getString(5);                                    String arriveTime = results.getString(6);                                    String meal = results.getString(7);                                    String flyingTime = String.valueOf(results.getDouble(8));                                    String miles = String.valueOf(results.getInt(9));                                    String aircraft = results.getString(10);                                    list.add(new FlightsBean(flightId, segmentNumber, startAirport,                                    departTime, endAirport, arriveTime, meal, flyingTime, miles, aircraft));                                    }                                    results.close();                                    prepStmt.close();                                    }                                    catch (SQLException sqlExcept)                                    {                                    sqlExcept.printStackTrace();                                    }                                    return (FlightsBean[])list.toArray(new FlightsBean[list.size()]);                                    }

origDestFlightList 方法使用 PreparedStatement 發(fā)出一個(gè) SQL 查詢,然后將結(jié)果放入一個(gè) FlightsBean[] 數(shù)組。下面顯示了 FlightsBean 的一個(gè)構(gòu)造函數(shù)。


清單 16. FlightsBean 的一個(gè)構(gòu)造函數(shù)
                                    public FlightsBean(String flight_id, String segNumber,                                    String origAirport, String depart_time, String destAirport,                                    String arrive_time, String food, String flying_time,                                    String mile, String jet)                                    {                                    flightId = flight_id;                                    segmentNumber = segNumber;                                    startAirport = origAirport;                                    departTime = depart_time;                                    endAirport = destAirport;                                    arriveTime = arrive_time;                                    meal = food;                                    flyingTime = flying_time;                                    miles = mile;                                    aircraft = jet;                                    }

當(dāng) origDestFlightList 方法填充好 FlightsBean 數(shù)組后,CheckFlightsServlet servlet 繼續(xù)進(jìn)行處理,結(jié)果被傳到 GetFlights.jsp 頁面。

在下一節(jié)中,您將使用 WTP 的 JSP 調(diào)試器來查看當(dāng)選擇一個(gè)航班時(shí) FlightsBean 中返回的值。

下一節(jié)將以 debug 模式啟動(dòng) Tomcat 服務(wù)器,所以這里先停止 Tomcat 服務(wù)器。為此,選擇工作區(qū)右下角的 Servers view 選項(xiàng)卡。然后在 Tomcat Server 行單擊右鍵并選擇 Stop。


圖 15. 在 WTP Servers 視圖中停止 Tomcat 服務(wù)器





使用 JSP Debugger

對(duì)于代碼的研究先告一段落,這里總結(jié)一下您通過探索和配置示例應(yīng)用程序所看到的東西:

  • WTP
    • 通過 Database Explorer 視圖配置到使用 Derby Client 驅(qū)動(dòng)程序的 Derby 10.1 數(shù)據(jù)庫的連接。
    • 從 Database Explorer 視圖抽取 FLIGHTS 表中的內(nèi)容。
    • 在 Database Explorer 視圖中,使用 Data > Open 菜單項(xiàng)插入一行到 FLIGHTS 表。
    • 從一個(gè) JSP 文件上使用 Run As > Run On Server 選項(xiàng)啟動(dòng) Tomcat 服務(wù)器。
    • 在 JSP 編輯器中打開和查看 JSP。
    • 使用 Servers 視圖停止 Tomcat 服務(wù)器。
  • Derby 插件
    • 添加 Apache Derby 特性到動(dòng)態(tài) Web 項(xiàng)目中。
    • 使用 Project Properties 菜單配置 Derby 系統(tǒng)屬性。
    • 通過 ij 運(yùn)行整個(gè) SQL 腳本。
    • 通過 ij 發(fā)出 SQL 命令。
    • 啟動(dòng)和停止 Derby Network Server。

 

現(xiàn)在讓我們來看 WTP 的 JSP 調(diào)試功能。

現(xiàn)在,在 Derby airlinesDB APP.USERS 表中至少有一個(gè)有效的用戶,您可能還添加了其他用戶。在運(yùn)行整個(gè)應(yīng)用程序之前,先在 GetFlights.jsp 頁面中設(shè)置一個(gè)斷點(diǎn),然后以 debug 模式啟動(dòng) Tomcat 服務(wù)器。

為設(shè)置斷點(diǎn),打開 GetFlights.jsp,在以 <c:set var="myradiobutton" 開始的那行代碼左邊的灰色區(qū)域單擊右鍵。選擇 Toggle Breakpoints,如下所示。


圖 16. 在 GetFlights.jsp 中設(shè)置斷點(diǎn)

這個(gè)斷點(diǎn)在左邊的灰色區(qū)域看上去像一個(gè)藍(lán)點(diǎn)?,F(xiàn)在從 Project Explorer 中(確保 Derby Network Server 仍在運(yùn)行),右鍵單擊 Welcome.jsp 并選擇 Debug As > Debug On Server。Tomcat Server 現(xiàn)在將以 Debug 模式啟動(dòng),并進(jìn)入 Welcome.jsp 頁面,該頁面提示輸入用戶 ID 和密碼。

輸入您之前輸入過的用戶 ID 和密碼,或輸入 slc 作為用戶 ID,slc 作為密碼。如果您沒有刪除已經(jīng)設(shè)置好的 cookie,那么您不必再次登錄,就可以在 Welcome.jsp 中選擇航班。Origin to Destination 中列出的航班并不都是直達(dá)的。選擇 Albuquerque 作為 Origin,選擇 Los Angeles 作為 Destination,因?yàn)檫@個(gè)航班是直達(dá)的。然后單擊 Submit Query。

這時(shí),Eclipse 應(yīng)該提示您切換到 Debug 透視圖。確認(rèn)切換透視圖。當(dāng)出現(xiàn) debug 透視圖時(shí),在工作區(qū)的右上角將出現(xiàn) Variables 視圖。在左下角,還將出現(xiàn) GetFlights.jsp 編輯器視圖,這個(gè)視圖表明您設(shè)置斷點(diǎn)的位置。

Variables 視圖可能不會(huì)立即有值出現(xiàn)。您可能需要進(jìn)入 Debug 視圖,并選擇已經(jīng)被掛起的線程。如下所示,當(dāng)您在 Debug 視圖中展開掛起的線程,并選擇 GetFlights.jsp 時(shí),Variables 視圖中將出現(xiàn)值。

在 Variables 視圖中,查找您的 core JSTL when 標(biāo)記。展開樹,找到 _jspx_th_c_when_0=WhenTag 項(xiàng)。見圖 17。


圖 17. 從 JSP Debug 透視圖中查看變量

注意 WhenTag 中對(duì)父標(biāo)記 ChooseTag 的引用。展開父標(biāo)記 ChooseTag,一起的還有父標(biāo)記 ForEachTag。展開 ForEachTag,最后展開等于 FlightsBean 的變量。如果您成功地執(zhí)行了這一系列動(dòng)作,那么 Variables 視圖看上去應(yīng)該如下所示。


圖 18. Debug 模式下的 FlightsBean 值

這個(gè)視圖顯示 FlightsBean 對(duì)象中的值,這是在選擇啟程機(jī)場為 Albuquerque,目的機(jī)場為 Los Angeles 的情況下得到的。當(dāng)為 Web 應(yīng)用程序排除故障,特別是像這里那樣查看變量時(shí),JSP 調(diào)試器極為有用。

現(xiàn)在單擊左上角菜單項(xiàng)上的 Resume 按鈕(看上去像一個(gè)綠色的箭頭),以跳過斷點(diǎn)。瀏覽器將顯示 GetFlights.jsp 頁面的輸出。在瀏覽器中,選擇可用的航班(航班 AA1111),并單擊 Book Flight 按鈕。

接下來的頁面給您最后一次機(jī)會(huì)預(yù)訂當(dāng)前航班或者查看其他航班。單擊 Book Flight 按鈕繼續(xù)。 接下來的頁面將如下所示。


圖 19. Flight History

當(dāng)您在前一個(gè)屏幕上單擊 Book Flight 時(shí),將有一行被插入到 APP.FLIGHTHISTORY 表中。由于您已經(jīng)知道如何使用 ijDatabase Explorer,您可以驗(yàn)證這一行是否真的插入到了表中。

至此,用戶可以返回并選擇一個(gè)新的航班,或者退出應(yīng)用程序。





結(jié)束語

在安裝和配置 WTP 平臺(tái)的過程中,您使用了外部的 Tomcat 服務(wù)?器,調(diào)試了一個(gè) JSP 文件,使用 Database Explorer 配置了到 10.1 Derby 數(shù)據(jù)庫的一個(gè)連接,并使用了 Database Explorer 來瀏覽一個(gè)表以及插入一行。

您學(xué)習(xí)了 Derby 插件的用法,包括添加 Apache Derby 特性,啟動(dòng)和停止 Network Server,使用 ij 運(yùn)行 SQL 腳本和發(fā)出即席 SQL,以及設(shè)置 derby.system.home 屬性。

您配置了 Web 應(yīng)用程序的 web.xml 文件,以便使用 Derby 作為數(shù)據(jù)源。

最后,您使用 JSTL SQL 標(biāo)記庫對(duì)被配置為數(shù)據(jù)源的 Derby 數(shù)據(jù)庫發(fā)出查詢。

本文有望為使用 WTP 和 Derby 插件中的多種工具提供一個(gè)堅(jiān)實(shí)的基礎(chǔ)。以這些基礎(chǔ)為起點(diǎn),您可以開發(fā)健壯的使用 Derby 作為數(shù)據(jù)源的 Web 應(yīng)用程序。






下載

描述 名字 大小 下載方法
Derby Database files for the Web Application LowFareAirData.zip 216 KB  FTP
|
HTTP
LowFare Air war file LowFareAir.war 31 KB  FTP
|
HTTP
關(guān)于下載方法的信息
Get Adobe? Reader?




參考資料

學(xué)習(xí)
  • 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文。

  • DerbyApache Derby 站點(diǎn)包含在線文檔、下載(源文件和二進(jìn)制文件)以及包括其他開放源碼項(xiàng)目在內(nèi)的綜合信息。您可以訂閱開發(fā)人員郵件列表和用戶郵件列表,或者瀏覽它們的檔案文件。

  • Derby Plug-insApache Derby Integration 中有一個(gè) Eclipse Plug-ins 專區(qū),這里有關(guān)于 Derby 插件的簡介,還有一個(gè)關(guān)于如何使用這些可以下載的 Derby 插件的實(shí)驗(yàn)。

  • Derby Plug-ins在 Eclipse 中開發(fā) Apache Derby 應(yīng)用程序 詳細(xì)講述了如何在 Eclipse 中使用 Derby 插件開發(fā)獨(dú)立的 Java 應(yīng)用程序。

  • JSTL:developerWorks 上很好的一個(gè)系列 JSTL 入門,這是極好的 JSTL 入門資料。

  • WTPWTP 網(wǎng)站包含了 WTP 的方方面面。具體來說,這里的教程很有用,當(dāng)碰到問題時(shí),訂閱新聞組也很有幫助。

  • Cloudscape information center 包含所有在線 Cloudscape 文檔。

  • developerWorks 提供了大量有關(guān) Cloudscape 的文章。


獲得產(chǎn)品和技術(shù)

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Tomcat 5.5 身份驗(yàn)證領(lǐng)域配置
在 Eclipse 中開發(fā) Apache Derby 應(yīng)用程序
開發(fā)Spring MVC應(yīng)用程序(1)
使用 Easy Struts for Eclipse 開發(fā) Struts
J2EE學(xué)習(xí)中一些值得研究的開源項(xiàng)目 - CSDN Java頻道
在Eclipse下,從安裝到使用Derby插件
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服