程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> J2EE探險者: 用於無狀態網絡的J2EE技術

J2EE探險者: 用於無狀態網絡的J2EE技術

編輯:關於JAVA

在最近幾年裡,Java 行業的發展呈指數級增長。作為一名企業應用程序開發人員、架構設計師或者技術經理,您可以從許多供應商、最佳實踐、規范和組件類型中為您的 Java 技術實現進行選擇。J2EE 探險者系列的目的是幫助您從這些選擇中找到一條途徑,對於任何一種給定的情形,協助您挑選合適的技術。

在本文,也就是第 1 部分中,我們將探討無狀態 J2EE 組件,並評估出最合適的組件來用於您的企業體系結構。說到無狀態、請求處理組件,可供選擇的 J2EE 技術主要有兩種:servlet 或 Enterprise JavaBeans 技術 ― 或更具體一點,無狀態會話 bean。

一般而言,servlet 和 EJB 組件是設計用於作為企業體系結構的事務管理組件。每一種技術都有其長處。servlet 體系結構的長處在於它的整體效率和相對簡單性。而 EJB 組件則更健壯,因此開發、維護和調試要更復雜。

我們首先簡要討論一下無狀態(相對於有狀態)網絡的質量,然後從正反兩方面詳細探討這兩種無狀態技術。在文章最後,我們泛泛地探討一下 J2EE 企業編程中最常見的一些應用程序設置,以及對應我們所討論的這兩種選擇的最佳技術解決方案。

請注意,從本文的目的出發,JSP(Java ServerPages)技術被認為是特殊類型的 servlet。考慮到在執行每個 JSP 頁面之前先將其轉換成 servlet,因此這種說法不難理解。因為 servlet 固有的無狀態性,所以我們只考慮無狀態會話 bean 以及它們為處理無狀態客戶機請求所提供的特性。本系列的下一篇文章將對有狀態會話 bean 與 servlet 和 HTTP 會話 API 進行比較。

無狀態網絡

可以將 Web 應用程序協議分為兩大類:無狀態和有狀態。協議的 狀態是指下一次傳輸可以“記住”這次傳輸信息的能力。有狀態協議能夠根據客戶機以前的請求創建上下文。無狀態協議沒有上下文;每個請求都是與服務器的獨立連接。

HTTP 就是一個很好的無狀態協議的示例,它建立在客戶機-服務器請求和響應的基礎之上。在 HTTP 中,不會為下一次請求維護這次請求中客戶機-服務器間交互的信息。

當然,由於無法維護狀態,因特網將只能成為漂亮的百科全書、電子黃頁以及 Shockwave.com 上很酷的動畫游戲。因此,出現了一些技巧在 HTTP 上模擬有狀態會話。有狀態信息可以存儲在 HTML 表單域或用戶機器的 cookie 中,也可以附到超級鏈接中。然後,應用程序開發人員負責管理、跟蹤和維護客戶機的狀態以確保會話過程順暢、安全以及讓人著迷。

servlet 的適用情況

servlet 體系結構被設計成靈活的、與平台無關的組件模型,它在服務器上執行,並處理客戶機的請求。Servlet 很 靈活,因為它們是由服務器的部署描述符(它是特定於服務器的)和 Web 應用程序部署描述符(它是由 J2EE 規范定義的,與服務器無關,例如 web.xml)兩者的組合唯一地配置的。Servlet 之所以 與平台無關是因為它們可以運行在任何 OS 上(這得益於 JVM),可以在任何 J2EE Web 服務器中運行(這得益於 J2EE 標准)。最後,servlet 體系結構是一個 組件模型,因為它使開發人員可以編寫周全的、可實現特定接口的組件。然後在運行時將這些組件組裝起來,以處理客戶機請求。

雖然 servlet 通常處理 HTTP 請求,但 servlet 體系結構與協議無關。servlet 接口定義了與 servlet 通信所需的基本方法,而不用考慮網絡協議。為了簡單起見以及由於 HTTP servlet 是最常用的類型,因此我們將只討論 HTTP servlet。事實上,如果從 HTTPServlet 擴展定制的 servlet 類,則無需擔心解析 HTTP 請求流、抽取參數或其它任何典型的 HTTP 處理活動中所涉及到的細節, 就能夠方便地使用和處理 HTTP 通信。

servlet 體系結構

人們通常將模型-視圖-控制器(MVC)設計模式應用於需要某類人機界面的情形。該模式源自 Smalltalk 社區,在那裡用它來構建靈活的且可重用的用戶界面。Servlet 天生就適合於 MVC 設計方法。在這種體系結構中, 模型是指正在被訪問數據的結構和類型。模型組件通常包含業務邏輯,業務邏輯控制數據訪問並為一個或多個視圖服務。視圖提供了用戶界面,用戶或應用程序組件可以通過用戶界面來訪問模型。可以用多個視圖來提供模型的各個界面。最後, 控制器組件協調整個通信。控制器處理客戶機輸入、操作模型以及決定將哪個視圖發送給給定的客戶機。

從體系結構角度來講,servlet 可充當控制器和視圖。通常,將 JSP 頁面用作視圖組件,將 JSP 頁面或純 servlet 用作控制器組件。Servlet 在處理如內容格式化和顯示、基本請求處理、安全請求等等之類的用戶交互工作時很有效。通常,servlet 會使用助手類(通常為 JavaBean 樣式的類)來處理繁重的工作,或使用這些類與後端組件進行相互操作。這就允許 servlet 層專注於客戶機交互,而不是業務處理。

Servlet 是非常輕量級的,因為只需要有限的資源來初始化以及維護 servlet 實例。servlet 的可伸縮性非常平滑和有效。在 servlet 體系結構下,給定的 servlet 實例通過為每個請求產生新的線程並在每個線程內執行 service() 方法來同時處理多個請求。圖 1 顯示了 servlet 實例的生命周期,展示了它的輕量級可伸縮性。

圖 1. servlet 線程模型

無論是否需要管理 servlet 容器、設置服務器負載均衡、處理簡單的 HTML 表單或甚至對 HTTP 數據流執行復雜的處理,servlet 體系結構和 API 都能使 Web 應用程序開發和部署變得非常容易。用 servlet 容器設置和管理 Web 服務器非常簡單,只需要很少的配置。對於服務器部署,通常一個或兩個 XML 文件就包含所有所需的配置設置。對 servlet 進行編程也很簡單。servlet API 對以下過程中所涉及到的細節進行了抽象:截取客戶機請求、將請求路由至相應的 servlet 實例、從線程池檢索線程、調用正確的方法來處理請求( doGet() 、 doPost() 或其它任何從 service() 方法調用的方法)以及甚至為抽取和處理編碼的 HTTP 數據提供方便的 API。

會話 bean 的適用情況

EJB 體系結構還被設計用來提供靈活的、與平台無關的、服務器端的組件模型。在這些特性和實現方面,EJB 規范是 Servlet 規范的翻版。通過使用用於部署階段綁定的部署描述符,兩種技術都具有靈活性;得益於 JVM 和 J2EE 規范,兩種技術都與平台無關;兩種技術都提供了服務器端組件模型,這兩種模型使用接口和抽象類以減少開發時間和麻煩,並確保了最優的組件重用性。另外,無狀態會話 bean 從 EJB 容器獲得了一些好處,包括聲明的安全性、聲明的事務上下文、與其它企業 bean 的可配置關系,以及可以方便地通過資源管理器連接工廠與其它 J2EE API(譬如 JMS、JavaMail 和 JDBC)集成。

最初,與企業 bean 通信是通過人機接口進行的,最終是通過 bean 的 home 接口或本地接口進行。由於外部客戶機不能使用本地接口,因此我們只探討遠程接口。通過使用 Java 遠程方法調用(RMI)與遠程接口進行通信。RMI 是特定於 Java 平台的網絡協議,它使 Java 對象可以與遠程 Java 對象進行交互,就好象該遠程對象在本地一樣。因此,只有 Java 組件(applet、servlet、AWT、Swing 和非 GUI Java 應用程序等)可直接用作 EJB 客戶機。其它任何客戶機類型(譬如手機、浏覽器或非 Java 應用程序)都必須通過 Java 應用程序進行通信。

EJB 體系結構

從體系結構的角度,會話 bean 可以用作視圖、控制器或甚至模型本身。通常,它們還實現虛包(Facade)模式或業務委派(Business Delegate)模式(請參閱 參考資料)。servlet(或 JSP 頁面)、幫助 servlet 的 JavaBean(或 JSP 頁面)、另一個企業 bean 可以訪問會話 bean,也可以直接通過 applet、Swing 應用程序或其它 Java 應用程序訪問會話 bean。

雖然到目前為止會話 bean 是最輕量級的 EJB 類型,但使用 EJB 容器和 EJB 體系結構是有代價的。EJB 容器需要占用服務器大量的處理能力和內存。不象 Java servlet 所采用的輕量級線程機制,EJB 組件需要創建和管理多個對象實例和相關資源(請參閱圖 2)。然而,較高的開銷所換來的好處是,在不犧牲很多響應時間和整體可伸縮性的情形下,EJB 組件向企業資源、事務和安全性檢查提供了有效的管理。因為無狀態會話 bean 不一定需要維護任何客戶機狀態,所以可以有效地合用無狀態會話 bean,使用它們來完成任何客戶機的請求。

圖 2. 企業 bean 管理

無論您需要管理 EJB 容器、設置服務器群集、為企業 bean 聲明配置設置還是需要利用容器眾多服務(包括安全性、事務管理和資源管理等)中的某項服務,EJB 體系結構和 API 都能使開發和部署健壯且功能齊全的 J2EE 應用程序變得出奇的簡單。部署描述符定義了容器和 bean 配置,EJB API 使用接口、bean 生命周期回調方法和工廠模式清晰地分隔開容器和企業 bean,同時仍使 bean 開發人員能方便地訪問容器服務。

選擇正確的技術

在某些情況下,確定使用 servlet(或 JSP 技術)、無狀態會話 bean 還是同時使用這兩者是一件非常簡單的事情,而在另外一些情況下,這種選擇卻需要不少技巧。通常的配置是使用 servlet 層來處理與 HTTP 客戶機的交互,然後將業務處理交給 EJB 層(主要由無狀態會話 bean 組成,偶爾也有實體 bean 組成)。在這一節,我們將研究幾個典型的應用程序情況,並討論解決這些情況的組件或最佳組件。

當您研究這些情況時,請牢記就每種技術您所了解的內容。尤其要記住,servlet 體系結構的輕量級線程模型使 servlet 的可伸縮性特別有效,而無狀態會話 bean 極好地平衡了健壯企業資源的訪問、恰當的響應時間和整體可伸縮性,有時無狀態會話 bean 能較好地適合比較重量級的應用程序。

應用程序客戶機

標准的應用程序客戶機是與另一系統或組件進行相互操作的用戶,而不是與應用程序進行相互操作的用戶。我們將研究三種典型的應用程序客戶機情況,以及它們最可能的解決方案:

如果客戶機是基於 Java 的,並且和服務器位於同一個防火牆之後,則最好的解決方案是使用 RMI,直接與應用程序服務器上的無狀態會話 bean 通信。

如果正在使用非 Java 客戶機,或者客戶機沒有位於服務器的防火牆之後,則您會希望使用 HTTP 協議來與 servlet 進行相互操作。(應該根據是否需要訪問由 EJB 組件所提供的廣泛的企業支持來決定是只使用 servlet 還是通過 servlet 訪問會話 bean)。

第三種情形較少見,但確實會出現。一些應用程序服務器供應商采用接受本機 IIOP 調用這樣的方式將其 EJB 容器公開,使 CORBA 客戶機將 EJB 組件看作本機 CORBA 應用程序。這允許非 Java 客戶機使用 IIOP 協議來與無狀態會話 bean 進行通信。在這種設置中,客戶機繞過了整個 Web 層,使用 IIOP 協議直接與業務層(無狀態會話 EJB 組件)通信。

企業應用程序集成(EAI)

EAI 通常使用一個或多個事務將兩個或多個企業應用程序集成到無縫值鏈中。由於 J2EE 對原有應用程序、消息傳遞系統、各種數據源和其它企業應用程序提供了廣泛的支持,所以它常常被用來將各種應用程序“粘合”成相連的集成系統。

在 EAI 這種情形中,servlet 和 EJB 組件作用差不多,因為在集成環境中使用 servlet 已經受到了限制。在這種罕見的情形中:應用程序需要調用 J2EE 方法,而除 HTTP 之外沒有其它機制可用,對於 EAI,servlet 是很有用的。否則,它只能帶來額外的開銷,以及造成體系結構不必要的復雜性。

不象 servlet,無狀態會話 bean 很好地被設計用於 EAI。無狀態會話 bean 是非常輕量級的(相對於有狀態會話 bean),可以方便地合用它們以確保極佳的可伸縮性。在 EAI 中常常需要狀態管理,但可以通過專門機制或通過 J2EE 事務來解決此問題。因此,從應用程序服務器中除去了狀態管理的負擔。

另一種可能性是調用 EJB 組件,就好象它是 CORBA(公共對象請求代理)組件。在被集成的一個或多個應用程序為 CORBA 組件的 EAI 情形中,這是特別有用的選項。

豐富的 GUI 客戶機

當構建豐富的用戶界面來訪問 J2EE 服務器端的功能時,您有幾種選擇:applet、獨立應用程序、Java Web Start 和本機 GUI。

applet 是作為 HTML 頁面的一部分裝入的,從而提供了豐富的動態用戶界面,人們一直都期望可以從 Web 上看到這種用戶界面。(在顯示文本方面,HTML 表現極佳,而在制作用戶界面方面,它卻不行)。applet 是一項功能強大的技術,因為它們與浏覽器無關,而且提供了豐富的 GUI 界面,同時,由 applet 沙箱來防止在未經許可的情況下訪問本地資源。對於更新客戶機接口問題,applet 還提供了引人注目的解決方案:只需在服務器上安裝最新的 applet 類和支持庫,在每次訪問 applet 時,客戶機會自動下載新文件。這種靈活性的代價是,每次訪問 applet 時,必須將 applet 類和所支持的庫下載到客戶機。

獨立應用程序被直接安裝在最終用戶的機器上。這些應用程序與浏覽器無關,它們被存儲在本地,而不需要從遠程站點下載。結果,啟動時間和響應時間大大縮短。獨立應用程序沒有 applet 的安全限制,所以可以較方便地訪問本地客戶機機器以及任何可以訪問的遠程服務器。不利的一面是,獨立應用程序極難維護和更新。每台機器在本地都有一個副本,所以不可能自動更新網絡上所有的應用程序。

Java Web Start實際上是 applet 和獨立應用程序的混合物,它是一項較新的技術,它有許多較突出的優點(關於更多這方面的信息,請參閱 參考資料)。象 applet 一樣,可以從 Web 浏覽器調用 Java Web Start,它也可以與 servlet 交互。與 applet 不同的是,Java Web Start 應用程序將文件緩存在本地硬盤,只有當需要時才下載額外的文件。可以從本地資源安裝或通過 Web 遠程安裝 Java Web Start 應用程序。此外,啟動的 GUI 是功能齊全的 Swing 客戶機。可以在不妨礙應用程序的情況下關閉浏覽器。其結果是結合了 applet 和非 applet 兩者的優點。然而,Java Web Start 並不是十全十美。它需要將所有資源都包含在本地 JAR 文件中(而不是松散的文件中);它不允許直接訪問資源(資源是通過抽象的資源管理機制來訪問的);它不支持本機應用程序的部署。

以下解決方案可應用於這三個豐富 GUI 組件類型中的任何一個:

如果客戶機和服務器分別位於防火牆的兩側,則您會希望客戶機通過 HTTP 與 servlet 通信。使用助手類,servlet 層可以進行簡單的業務處理(解析 XML 文檔、通過 JDBC 訪問數據源、用 JavaMail 或 JMS 來處理簡單的消息或者甚至用 JTS/JTA 協調簡單的事務)。對於較復雜的需求或者需要較頻繁地請求企業資源,業務處理應該用會話 bean。

如果客戶機和服務器都位於同一防火牆之後,則純粹使用 RMI 調用來直接與應用程序服務器通信,這樣可以提高性能和方便編程。在這種情形,使用 servlet 只能帶來額外的開銷,以及造成體系結構不必要的復雜性。在使用 applet 或 Java Web Start 的情況下,帶有 applet 或 Java Web Start 應用程序鏈接的 HTML 文檔可能最初使用 servlet,但在後來,為了處理客戶機請求,客戶機將與一個或多個無狀態會話 bean 建立直接的 RMI 連接。

最後,如果客戶機使用 非 Java GUI(即本機 GUI),並且客戶機需要管理復雜的事務或一系列的事務,則您會希望考慮選擇使用這種方法:調用 EJB 組件,就好象它是 CORBA 組件。

Web 應用程序

在標准的基於 Web 的應用程序(譬如 Web 浏覽器)情形下,您會采用支持 HTTP 的客戶機,它需要訪問一個或多個後端業務服務。在這種情形下,不需要考慮客戶機位於防火牆的哪一側,因為必須要使用 servlet。顯而易見,HTTP 的需求會利用 Web 層。實質上將根據對 EJB 容器服務的相對需求來決定是否使用 EJB 組件。

多種客戶機類型

最後一種情形是需要多種客戶機類型。也許外部客戶需要使用基於 Web 浏覽器的客戶機,而內部員工需要使用標准的桌面、豐富的 GUI。在提供高性能和可靠性的需求與重用需求之間,如何平衡?

如果不需要管理復雜的事務,或者不需要訪問多個企業資源,則可以簡單地使用與一系列助手類進行相互操作的 servlet 層來進行業務處理。外部浏覽器客戶機將通過這個 Web 層與系統進行相互操作。然後,重用助手 bean 來直接為內部應用程序的請求提供服務,或者內部應用程序通過 servlet 層進行通信。雖然這樣能解決問題,但它不是最干淨、最有效或可伸縮性最好的解決方案。

較常用的解決方案是將業務邏輯放入無狀態會話 bean 中,讓外部應用程序通過 servlet 層與應用程序服務器通信,讓內部應用程序直接與 bean 通信。這種做法使表示與業務邏輯分離得最徹底,使內部應用程序直接地、自由地訪問業務邏輯,從而在達到同一目的的情況下,這種做法采用的抽象最少。

結束語

在 J2EE 探險者系列的第 1 部分中,我們研究了使用 Java servlet 和無狀態會話 bean 來完成客戶機的請求時,它們之間相對的長處和短處。這裡所討論的各種情形並沒有涵蓋所有情況,但這些情形代表了無狀態通信環境中 servlet 和會話 EJB 最常用的一些情況。

下個月,我們將從正反兩面權衡在 Web 層(使用 servlet 和 HTTPSessionAPI )和業務層(使用有狀態會話 bean)中管理狀態。到那時,祝您“探路”愉快!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved