級別: 初級 Neal Sanche , Java 開發(fā)人員, Pure Technologies
2005 年 8 月 24 日 在前兩篇 developerWorks 文章(參閱 參考資料)
中,作者 Neal Sanche 使用簡單的電話簿應(yīng)用程序來展示如何將 Apache Geronimo 應(yīng)用服務(wù)器連接到數(shù)據(jù)庫,以及如何使用
Geronimo 創(chuàng)建具有 Enterprise JavaBeans (EJB) 后端的基于 Struts 的 Web
應(yīng)用程序。本文進(jìn)一步使用電話簿應(yīng)用程序來展示如何創(chuàng)建獨(dú)立客戶端應(yīng)用程序以操作電話號碼數(shù)據(jù)庫。您還將學(xué)習(xí)如何配置 Geronimo
以允許來自特定客戶端的安全訪問。 簡介 本文將展示如何開發(fā)可以與運(yùn)行在 Geronimo 應(yīng)用服務(wù)器內(nèi)部的 EJB 應(yīng)用程序通信的獨(dú)立(胖)客戶端。基于我的前兩篇文章 ——“將數(shù)據(jù)庫連接到 Geronimo 應(yīng)用服務(wù)器的三種方法”(developerWorks,2005 年 6 月)和“利用 Geronimo 深入 EJB Web 應(yīng)用程序”
(developerWorks,2005 年 7 月)—— 本文向您展示一個(gè)連接到使用 Geronimo EJB
應(yīng)用程序構(gòu)建的小型電話簿數(shù)據(jù)庫的 Swing
客戶端。您將閱讀簡要的設(shè)計(jì)說明,然后閱讀有關(guān)運(yùn)行該應(yīng)用程序所需的客戶端庫的信息。接下來我將介紹聯(lián)系服務(wù)器并對服務(wù)器上遠(yuǎn)程無狀態(tài)會話 bean
執(zhí)行操作的方法。最后,您將學(xué)習(xí)如何開發(fā)、編譯并運(yùn)行客戶端應(yīng)用程序,以及如何配置服務(wù)器以允許來自網(wǎng)絡(luò)中特定客戶端的安全訪問。 要最有效地利用本文,您需要熟悉用于構(gòu)建 Java 桌面應(yīng)用程序的 Java Swing API 以及 Apache Maven 構(gòu)建系統(tǒng)(參閱 參考資料 以鏈接到 Maven Web 站點(diǎn))。
設(shè)計(jì)概述 首先簡要介紹一下示例應(yīng)用程序設(shè)計(jì) —— 一個(gè)描述電話簿客戶端應(yīng)用程序的統(tǒng)一建模語言 (Unified Modeling Language, UML) 部署圖 —— 如 圖 1 所示。客戶端應(yīng)用程序通過其 EJB 端口連接到 Geronimo,并與 PhoneBook Session EJB 對話以通過 PhoneBook Entry Container-Managed Persistence (CMP) 操作數(shù)據(jù)庫中的數(shù)據(jù)。 圖 1. 電話簿客戶端部署圖

Geronimo 的默認(rèn)發(fā)行版對 EJB 端口有限制。僅當(dāng)客戶端應(yīng)用程序運(yùn)行在同一機(jī)器上并且通過環(huán)回地址(localhost 或 127.0.0.1) 連接時(shí)才能連接到該端口。本文稍后的 配置 Geronimo 的 EJB 端口 一節(jié)提供了有關(guān)如何讓其他機(jī)器上的客戶端訪問服務(wù)器的詳細(xì)信息。
用于連接到 Geronimo 的客戶端庫 要讓客戶端應(yīng)用程序能夠連接到 Geronimo 的 EJB 端口并與 EJB 層通信,客戶端類路徑中必須要有下列 Java 庫: - geronimo-spec-j2ee-1.4-rc4.jar
- geronimo-kernel-1.0-SNAPSHOT.jar
- geronimo-j2ee-1.0-SNAPSHOT.jar
- geronimo-security-1.0-SNAPSHOT.jar
- cglib-nodep-2.1.jar
- openejb-core-2.0-SNAPSHOT.jar
 | 對構(gòu)建結(jié)構(gòu)的備注
因?yàn)閷η懊嫖恼轮写a的構(gòu)建結(jié)構(gòu)進(jìn)行了一些小的修改,所以本文的代碼包含了電話簿應(yīng)用程序和電話簿客戶端應(yīng)用程序。下載 包括了有關(guān)如何使用 Maven 構(gòu)建這兩個(gè)應(yīng)用程序的詳細(xì)說明。 |
|
從源代碼編譯 Geronimo 時(shí),當(dāng)您使用 Maven 構(gòu)建腳本來編譯電話簿客戶端應(yīng)用程序時(shí),這些庫被放置到本地 Maven 資源庫中且可供訪問。您可以在 project.xml 文件的依賴關(guān)系部分中查看所有這些庫位于 Maven 資源庫的哪個(gè)位置。 其中一些庫在客戶端與服務(wù)器的通信中起著非常重要的作用。Geronimo 使用 CGLib 庫來執(zhí)行動態(tài)代理生成。這使得服務(wù)器動態(tài)生成遠(yuǎn)程調(diào)用服務(wù)器端組件的代碼。如果在調(diào)試器中檢查客戶端上 InitialContext 對象的 lookup() 方法返回的一個(gè)對象,可以看到動態(tài)生成的對象的類名包括 CGLib 。geronimo-spec-j2ee.jar
文件包含所有的 Sun Java 2 Platform, Enterprise Edition (J2EE)
接口和類。沒有該文件,客戶端將無法理解任何動態(tài)代理實(shí)例。openejb-core.jar 文件是與服務(wù)器的 EJB
端口進(jìn)行對話所必需的。用于在 Geronimo 服務(wù)器中執(zhí)行遠(yuǎn)程目錄查詢的 Java Naming and Directory
Interface (JNDI) 類就在該 .jar 文件中。最后的三個(gè) .jar 文件提供了其他支持類,比如與 Geronimo
對話的安全主體。
執(zhí)行遠(yuǎn)程會話本地查詢 客
戶端通信部分的實(shí)現(xiàn)十分簡單。將客戶端連接到服務(wù)器時(shí),Geronimo 與其他任何 J2EE 服務(wù)器沒有任何不同,遵守健全的通過 JNDI
查詢和遠(yuǎn)程方法調(diào)用 (RMI) 進(jìn)行的通信標(biāo)準(zhǔn)。JNDI 查詢是獲得對遠(yuǎn)程對象的引用的標(biāo)準(zhǔn)訪問。要通過 JNDI 進(jìn)行連接,必須使用大量特定于
Geronimo 的屬性來創(chuàng)建 InitialContext 實(shí)例,該實(shí)例用于執(zhí)行查詢。 清單 1 展示了有關(guān)如何創(chuàng)建會話的示例。 清單 1. 創(chuàng)建到 Geronimo 托管會話 bean 的遠(yuǎn)程會話
import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject;
public void Connect() { String hostName = getHostName(); String port = getPort();
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.openejb.client.RemoteInitialContextFactory"); props.setProperty("java.naming.provider.url", hostName+":"+port); props.setProperty("java.naming.security.principal", "username"); props.setProperty("java.naming.security.credentials", "passwd");
Context ic; try { ic = new InitialContext(props); PhoneBookSessionHome sessionHome = (PhoneBookSessionHome) PortableRemoteObject.narrow( ic.lookup(PhoneBookSessionHome.JNDI_NAME), PhoneBookSessionHome.class); phoneBookSession = sessionHome.create(); } catch (Throwable ex) { ex.printStackTrace(); } finally { if (ic != null) { ic.close(); } } }
|
如 清單 1 所示,創(chuàng)建了 Properties 對象并設(shè)置了四個(gè)屬性。第一個(gè)并且是最重要的屬性是 java.naming.factory.initial 屬性,它必須設(shè)置為 org.openejb.client.RemoteInitialContextFactory 。其他屬性指定提供者 URL 以及安全主體和憑證。提供者 URL 是用冒號隔開的主機(jī)名和端口。 前已提及,EJB 端口當(dāng)前只接受從客戶端連接到 127.0.0.1 或 localhost 的連接。默認(rèn)端口是 4201。盡管如此,主機(jī)名和端口都可以進(jìn)行配置。有關(guān)詳細(xì)信息,請參閱 配置 Geronimo 的 EJB 端口 一節(jié)。 創(chuàng)建好屬性之后,就可以創(chuàng)建并使用 InitialContext 實(shí)例了。通過將屬性傳遞給構(gòu)造函數(shù)完成這一操作。創(chuàng)建好實(shí)例之后,可以執(zhí)行查詢。清單 1 包括一行復(fù)雜的代碼,該行執(zhí)行查詢并對結(jié)果執(zhí)行 PortableRemoteObject.narrow() 。對于向用戶隱藏有關(guān)協(xié)議傳輸 —— RMI 或者可能是 Internet Inter-ORB Protocol (IIOP)—— 的詳細(xì)信息,這是必需的。完成之后,遠(yuǎn)程會話就可供使用了。在 清單 1 中,該行只創(chuàng)建了新 PhoneBookSession,并將其存儲在一個(gè)字段中以供將來使用。 具有對遠(yuǎn)程會話的引用之后,該引用可用于所有操縱電話簿數(shù)據(jù)庫信息的操作。現(xiàn)在只需要一個(gè)應(yīng)用程序來練習(xí)該遠(yuǎn)程會話。
客戶端的設(shè)計(jì)和開發(fā) 現(xiàn)
在我們來深入研究一個(gè)小 Swing 應(yīng)用程序的設(shè)計(jì)和開發(fā),這個(gè)小應(yīng)用程序用來瀏覽、創(chuàng)建、刪除和修改電話簿數(shù)據(jù)庫條目。我盡量將 Swing
行話減到最少,以防您比較熟悉的是另一種 GUI 技術(shù),比如 Standard Widget Toolkit
(SWT)。事實(shí)上,如果需要的話,應(yīng)用程序架構(gòu)已經(jīng)使得將顯示從應(yīng)用程序內(nèi)部邏輯分離出來并將其連接到另一種 GUI 技術(shù)變得非常容易。 應(yīng)用程序架構(gòu)如 圖 2 所示,這是一個(gè)詳細(xì)顯示應(yīng)用程序靜態(tài)結(jié)構(gòu)的 UML 類圖。 圖 2. 客戶端應(yīng)用程序的 UML 類圖

圖 2 中帶綠色陰影的類是主要的應(yīng)用程序類。Main 類是包含菜單和拆分窗格(其左側(cè)是 PhoneNumberListPanel ,右側(cè)是 PhoneBookEditorPanel )的框架。該菜單還允許用戶設(shè)置連接到哪個(gè)服務(wù)器的首選項(xiàng),連接到服務(wù)器,并退出程序。Application 類是一個(gè)單身類(singleton class),用作應(yīng)用程序的所有操作的控制器。它是惟一一個(gè)執(zhí)行 EJB 操作的類,并保存對 PhoneBookSession 無狀態(tài)會話 bean 的引用。 橙色的兩個(gè)接口定義系統(tǒng)中的主要事件。每當(dāng) Application 決定電話號碼列表需要更新時(shí),就會激活 DataChangeEvent 。PhoneNumberListModel 注冊該事件。因?yàn)樗?PhoneNumberListPanel 中的主要數(shù)據(jù)模型列表視圖,所以列表是通過模型更改來更新的。這與 Swing 應(yīng)用程序的設(shè)計(jì)方法一致。 PhoneNumberListPanel 和 PhoneBookEditorPanel 類都實(shí)現(xiàn) PhoneBookSelectionListener 接口并注冊來自 Application 單身類的事件。當(dāng)它們收到事件時(shí),它們相應(yīng)地更新當(dāng)前的選擇。如果是 PhoneBookEditorPanel ,當(dāng)前選擇導(dǎo)致 Name 和 Number 字段由來自當(dāng)前選擇的電話簿條目中的數(shù)據(jù)填充。
如果希望節(jié)省編寫用戶接口代碼的時(shí)間,通常可以在 Internet 上找到高質(zhì)量的免費(fèi)工具。優(yōu)秀的工具有 JGoodies Forms 1.0.5 和 FormLayoutMaker,F(xiàn)ormLayoutMaker 是一個(gè)用于可視化創(chuàng)建窗體的小工具(參閱 參考資料 以獲得到這些工具的鏈接)。FormLayoutMaker 工具生成代表 JGoodies 窗體布局約束的 XML 文件。這些工具幫助我快速創(chuàng)建了 Phone Number 編輯面板和 Preferences 面板的窗體。
構(gòu)建應(yīng)用程序 編
譯應(yīng)用程序有兩種方法。我使用 Eclipse Visual Editor (VE) 插件 1.2 版本在 Eclipse
中開發(fā)了該應(yīng)用程序。它生成應(yīng)用程序的大部分代碼框架,但它是以一種非入侵的方式完成的(沒有代碼標(biāo)記和不可訪問的代碼塊),所以如果沒有安裝 VE
的話也應(yīng)該沒有問題。可以只加載項(xiàng)目并嘗試運(yùn)行它。 您可能需要設(shè)置 MAVEN_REPO 構(gòu)建變量以指向本地 Maven 資源庫。還需要構(gòu)建與本文一起提供的源代碼中包括的 Geronimo 和 PhoneBook 服務(wù)器應(yīng)用程序(參閱 下載)。這是因?yàn)椋幾g客戶端應(yīng)用程序,包含服務(wù)器應(yīng)用程序中 EJB 接口的 .jar 文件必須發(fā)布到本地 Maven 資源庫中。PhoneBook 的 Maven 構(gòu)建腳本通過下列 Maven 構(gòu)建腳本段完成該操作: 清單 2. Maven 構(gòu)建腳本段
<goal name="client" prereqs="java:compile"> <ant:jar destfile="target/${pom.artifactId}-client.jar"> <fileset dir="target/classes"> <include name="**/*.class"/> </fileset> </ant:jar> <artifact:install artifact="target/${pom.artifactId}-client.jar" type="jar" project="${pom}"/> </goal>
|
用于構(gòu)建應(yīng)用程序的第二種方法就是使用
Maven。在 PhoneBook 目錄中解壓文件并運(yùn)行 maven 命令。然后在 PhoneBookClient
目錄中進(jìn)行相同操作。如果一切順利,就已經(jīng)在目標(biāo)子目錄中創(chuàng)建了 UberJar —— 一個(gè)包含運(yùn)行客戶端所需的所有內(nèi)容的 JAR 文件。 兩種構(gòu)建方法運(yùn)行得同樣好。使用 Maven 方法的優(yōu)點(diǎn)是如果您尚未下載依賴關(guān)系,則它會自動從 ibiblio Web 站點(diǎn)(參閱 參考資料)上的遠(yuǎn)程 Maven 資源庫中下載這些依賴關(guān)系。所以如果 Eclipse 中的依賴關(guān)系有問題,就在項(xiàng)目上至少運(yùn)行一次 Maven 來校正缺少的庫。
運(yùn)行應(yīng)用程序 確保 PhoneBook 服務(wù)器應(yīng)用程序部署到 Geronimo 服務(wù)器中且正在運(yùn)行。然后鍵入下列命令: java -jar phonebook-client-uber.jar
|
將會看到應(yīng)用程序彈出,如 圖 3 所示。 圖 3. Geronimo 電話簿客戶端應(yīng)用程序

首先,從 File 菜單中選擇 Connect。如果是連接到 localhost:4201 端口,則應(yīng)該獲得一個(gè)連接;否則,控制臺窗口將會顯示錯(cuò)誤消息。可以通過選擇 Edit > Preferences、更改信息并嘗試重新連接來更改連接的服務(wù)器和端口。一旦連接上之后,可以通過在電話號碼編輯器中鍵入姓名和號碼并單擊 Save 來創(chuàng)建新記錄。該記錄將顯示在姓名列表中。通過選擇條目并單擊 Delete 來刪除條目。通過選擇條目、進(jìn)行修改并單擊 Save 來更改條目。
配置 Geronimo 的 EJB 端口 當(dāng)
前,配置 Geronimo 的 EJB 端口的方法需要編輯 XML 文件,然后重新編譯 Geronimo。Tom McQueeney 的大型
Geronimo Live blog 上的一篇短文清楚介紹了如何使用
openejb\modules\assembly\src\plan\j2ee-server-plan.xml 文件更改 Geronimo
Jetty 監(jiān)聽端口的詳細(xì)信息(參閱 參考資料 以鏈接到該 blog)。同一文件還包含 EJB 端口的配置信息(參閱 清單 3)。 清單 3. j2ee-server-plan.xml 文件中的代碼段
<gbean name="EJBNetworkService" class="org.openejb.server.StandardServiceStackGBean"> <attribute name="name">EJB</attribute> <attribute name="port">4201</attribute> <attribute name="address">127.0.0.1</attribute> <attribute name="allowHosts">127.0.0.1</attribute> <attribute name="logOnSuccess">HOST,NAME,THREADID,USERID</attribute> <attribute name="logOnFailure">HOST,NAME</attribute> <reference name="Executor"><name>DefaultThreadPool</name></reference> <reference name="Server"> <gbean-name>openejb.server:name=EJBServer,*</gbean-name> </reference> </gbean>
|
您需要編輯 j2ee-server-plan.xml 文件并更改 allowHosts 屬性。Geronimo 支持許多不同類型的地址。必須用下列模式之一輸入逗號分隔的地址列表: - 最后一格為 0 的 IP 地址。例如,192.168.10.0 允許 192.168.10 網(wǎng)絡(luò)上的任何機(jī)器與服務(wù)器通信。
- 任何完全指定的 IP 地址。
- 分解的 IP 地址。這是一種特殊模式,允許指定地址的網(wǎng)絡(luò)部分和以大括號擴(kuò)住的主機(jī)地址列表。例如,192.168.10.{5,6,7} 允許以下三個(gè)機(jī)器訪問服務(wù)器:192.168.10.5、192.168.10.6 和 192.168.10.7。
- 網(wǎng)絡(luò)掩碼 IP 地址。這是網(wǎng)絡(luò)管理員熟悉的一種地址。基于精確的位模式匹配規(guī)則(超出本文范圍),IP 地址與網(wǎng)絡(luò)掩碼相匹配。例如,192.168.255.255 允許 192.168.* 網(wǎng)絡(luò)中的所有地址訪問服務(wù)器。
- 準(zhǔn)確的 IPv6 地址。當(dāng)將來的 IP 網(wǎng)絡(luò)到來時(shí),Geronimo 將準(zhǔn)備好服務(wù),允許列出特定的 IP 地址。
- 網(wǎng)絡(luò)掩碼 IPv6 地址。
有
關(guān)服務(wù)器接受的特定模式的詳細(xì)信息,請咨詢源代碼文件 —— ServiceAccessController.java —— 位于來源的
openejb\modules\core\src\java\org\openejb\server
目錄中。在此將會找到與支持的每個(gè)地址類型相匹配的明確的正則表達(dá)式。 對 j2ee-server-plan.xml 文件進(jìn)行修改之后,重新編譯并更新服務(wù)器部署,您將具有一個(gè)專門滿足您需要的服務(wù)器。(如果只想查看針對同一機(jī)器上的服務(wù)器運(yùn)行的客戶端,則無需這樣做。默認(rèn)情況下,Geronimo 被配置來完成這些操作。)
結(jié)束語 本
文提供了一個(gè)構(gòu)建獨(dú)立(胖)客戶端的具體示例,該客戶端可以與運(yùn)行在 Geronimo 應(yīng)用服務(wù)器內(nèi)部的 EJB
應(yīng)用程序進(jìn)行對話。Geronimo 團(tuán)隊(duì)已經(jīng)認(rèn)真實(shí)現(xiàn)了健全的標(biāo)準(zhǔn),推廣用簡單的 JNDI 查詢方法獲得與無狀態(tài)會話 bean
的遠(yuǎn)程連接。如果只想讓簡單的應(yīng)用程序運(yùn)行,那么這是一個(gè)好消息,因?yàn)樗恍枰帉懮倭看a。 按照我所介紹的模式,您能夠?qū)⒃S多比較大的
數(shù)據(jù)庫連接到與 Geronimo 服務(wù)器位于同一機(jī)器上的客戶端應(yīng)用程序。使用本文提供的指示,您還能夠配置 Geronimo
服務(wù)器以允許從連接到您的網(wǎng)絡(luò)或 Internet 上的其他機(jī)器訪問服務(wù)器 EJB 端口。不妨嘗試一下。
下載 描述 | 名字 | 大小 | 下載方法 |
---|
Source code for the phonebook application | PhonebookClient.zip | 227 KB |
FTP |
參考資料
 |
關(guān)于作者  | 
| Neal
Sanche 是一位最近才涉足 Microsoft? .NET 世界的 Java
開發(fā)人員,他正在克服困難脫離他原來習(xí)慣了的開發(fā)環(huán)境。他的經(jīng)驗(yàn)包括開發(fā)多個(gè)商業(yè) J2EE 應(yīng)用程序和多個(gè)獨(dú)立 Java
應(yīng)用程序。在業(yè)余時(shí)間,他作曲、攝影并撰寫技術(shù)文章。訪問他的 Web 站點(diǎn) 可以看到相應(yīng)的多個(gè)示例。您可以通過 neal@nsdev.org 與 Neal 聯(lián)系。 |
|