日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

J2EE的13種核心技術(shù)

系統(tǒng) 2470 0

一、內(nèi)容簡介

? ?Steven Gould
在文中介紹了 J2EE 13 種核心技術(shù): JDBC JNDI EJBs RMI JSP Java Servlets XML JMS Java IDL JTS JTA JavaMail JAF 。為了聯(lián)系實(shí)際, Gould 基于 WebLogic 應(yīng)用服務(wù)器來自 BEA Systems 公司的一種廣為應(yīng)用的產(chǎn)品環(huán)境來介紹 J2EE 的這些技術(shù)。
? ?Java
最初在瀏覽器和客戶端機(jī)器中粉墨登場,當(dāng)時(shí)很多人質(zhì)疑它是否適合做服務(wù)器端的開發(fā)。現(xiàn)在隨著對 J2EE 第三方支持的增多, Java 被廣泛接納為開發(fā)企業(yè)級服務(wù)器端解決方案的首選平臺(tái)之一。
? ?J2EE
平臺(tái)由一整套服務(wù) (Services) 、應(yīng)用程序接口 (APIs) 和協(xié)議構(gòu)成,它對開發(fā)基于 Web 的多層應(yīng)用提供了功能支持。在本文中我將解釋支撐 J2EE 13 種核心技術(shù): JDBC JNDI EJBs RMI JSP Java Servlets XML JMS Java IDL JTS JTA JavaMail JAF ,同時(shí)還將描述在何時(shí)、何處需要使用這些技術(shù)。當(dāng)然我還要介紹這些不同技術(shù)之間如何交互。
? ?
此外,為了讓您更好地感受 J2EE 的真實(shí)應(yīng)用,我將在 WebLogic 應(yīng)用服務(wù)器環(huán)境下來介紹這些技術(shù)。不論對于 WebLogic 應(yīng)用服務(wù)器和 J2EE 的新手,還是那些想了解 J2EE 能帶來什么好處的項(xiàng)目管理者和系統(tǒng)分析員,相信本文一定很有參考價(jià)值。

?
二、宏觀印象 : 分布式結(jié)構(gòu)和 J2EE

? ?
過去二層化應(yīng)用 -- 通常被稱為 C/S 應(yīng)用 -- 是大家談?wù)撟疃嗟摹T诤芏嗲闆r下,服務(wù)器提供的唯一服務(wù)就是數(shù)據(jù)庫服務(wù)。在這種解決方案中,客戶端程序負(fù)責(zé)數(shù)據(jù)訪問、實(shí)現(xiàn)業(yè)務(wù)邏輯、用合適的樣式顯示結(jié)果、彈出預(yù)設(shè)的用戶界面、接受用戶輸入等。 C/S 結(jié)構(gòu)通常在第一次部署時(shí)較容易,但難于升級或改進(jìn),且經(jīng)常基于某種專有的協(xié)議,通常是某種數(shù)據(jù)庫協(xié)議。它使得重用業(yè)務(wù)邏輯和界面邏輯非常困難。更重要的是,在 Web 時(shí)代,二層化應(yīng)用通常不能體現(xiàn)出很好的伸縮性,因而很難適應(yīng) Internet 的要求。
? ?Sun
設(shè)計(jì) J2EE 的部分起因就是想解決二層結(jié)構(gòu)的缺陷,于是 J2EE 定義了一套標(biāo)準(zhǔn)來簡化 N 層企業(yè)級應(yīng)用的開發(fā)。它定義了一套標(biāo)準(zhǔn)化組件,并為這些組件提供完整的服務(wù)。 J2EE 還自動(dòng)為應(yīng)用程序處理了很多實(shí)現(xiàn)細(xì)節(jié),如安全、多線程等。用 J2EE 開發(fā) N 層應(yīng)用包括將二層結(jié)構(gòu)中的不同層面切分成許多層。一個(gè) N 層化應(yīng)用 A 能夠?yàn)橐韵碌拿糠N服務(wù)提供一個(gè)分開的層:
? ?
顯示:在一個(gè)典型 Web 應(yīng)用中,客戶端機(jī)器上運(yùn)行的瀏覽器負(fù)責(zé)實(shí)現(xiàn)用戶界面。
? ?
動(dòng)態(tài)生成顯示:盡管瀏覽器可以完成某些動(dòng)態(tài)內(nèi)容顯示,但為了兼容不同的瀏覽器,這些動(dòng)態(tài)生成工作應(yīng)該放在 Web 服務(wù)器端進(jìn)行,使用 JSP Servlets XML XSLT
? ?
業(yè)務(wù)邏輯:業(yè)務(wù)邏輯適合用 Session EJBs( 后面將介紹 ) 來實(shí)現(xiàn)。
? ?
數(shù)據(jù)訪問:數(shù)據(jù)訪問適合用 Entity EJBs( 后面將介紹 ) JDBC 來實(shí)現(xiàn)。
? ?
后臺(tái)系統(tǒng)集成:同后臺(tái)系統(tǒng)的集成可能需要用到許多不同的技術(shù),至于何種最佳,需要根據(jù)后臺(tái)系統(tǒng)的特征而定。
? ?
您可能開始詫異:為什么有這么多的層?事實(shí)上,多層方式可以使企業(yè)級應(yīng)用具有很強(qiáng)的伸縮性,它允許每層專注于特定的角色。如讓 Web 服務(wù)器負(fù)責(zé)提供頁面,應(yīng)用服務(wù)器處理應(yīng)用邏輯,而數(shù)據(jù)庫服務(wù)器提供數(shù)據(jù)庫服務(wù)。
? ?
由于 J2EE 建立在 J2SE 的基礎(chǔ)上,所以具備了 J2SE 的所有優(yōu)點(diǎn)和功能。包括 編寫一次,到處可用 的可移植性、通過 JDBC 訪問數(shù)據(jù)庫、同原有企業(yè)資源進(jìn)行交互的 CORBA 技術(shù),及一個(gè)經(jīng)過驗(yàn)證的安全模型。在這些基礎(chǔ)上, J2EE 又增加了對 EJB Java Servlet JSP XML 技術(shù)的支持。

三、分布式結(jié)構(gòu)與 WebLogic 應(yīng)用服務(wù)器
? ?J2EE
提供了一個(gè)框架 ( 一套標(biāo)準(zhǔn) API) 用于開發(fā)分布式結(jié)構(gòu)的應(yīng)用,這個(gè)框架的實(shí)際實(shí)現(xiàn)留給了第三方廠商。部分廠商只是專注于整個(gè) J2EE 架構(gòu)中的的特定組件,如 Apache Tomcat 提供了對 JSP Servlet 的支持, BEA 系統(tǒng)公司則通過其 WebLogic 應(yīng)用服務(wù)器產(chǎn)品為整個(gè) J2EE 規(guī)范提供了一個(gè)較為完整的實(shí)現(xiàn)。
? ?WebLogic
服務(wù)器已使建立和部署伸縮性較好的分布式應(yīng)用的過程大為簡化。 WebLogic J2EE 代你處理了大量常規(guī)的編程任務(wù),包括提供事務(wù)服務(wù)、安全領(lǐng)域、可靠的消息、名字和目錄服務(wù)、數(shù)據(jù)庫訪問和連接池、線程池、負(fù)載平衡和容錯(cuò)處理等。通過以一種標(biāo)準(zhǔn)、易用的方式提供這些公共服務(wù),象 WebLogic 服務(wù)器這樣的產(chǎn)品造就了具有更好伸縮性和可維護(hù)性的應(yīng)用系統(tǒng),使其為大量的用戶提供了增長的可用性。

四、 J2EE 技術(shù)
? ?
在接下來的部分里,我們將描述構(gòu)成 J2EE 的各種技術(shù),且了解 WebLogic 服務(wù)器是如何在一個(gè)分布式應(yīng)用中對它們進(jìn)行支持的。最常用的 J2EE 技術(shù)應(yīng)該是 JDBC JNDI EJB JSP Servlets ,對這些我們將作更仔細(xì)的考察。

1. ? ? Java Database Connectivity (JDBC)

? ?JDBC API
以一種統(tǒng)一的方式來對各種數(shù)據(jù)庫進(jìn)行存取。和 ODBC 一樣, JDBC 為開發(fā)人員隱藏了不同數(shù)據(jù)庫的不同特性。另外,由于 JDBC 建立在 Java 的基礎(chǔ)上,因此還提供了數(shù)據(jù)庫存取的平臺(tái)獨(dú)立性。 JDBC 定義了 4 種不同的驅(qū)動(dòng)程序,現(xiàn)分述如下:
? ?
類型 1 JDBC-ODBC Bridge
? ?
JDBC 出現(xiàn)的初期, JDBC-ODBC 橋顯然是非常有實(shí)用意義的,通過 JDBC-ODBC 橋,開發(fā)人員可用 JDBC 來存取 ODBC 數(shù)據(jù)源。不足的是需要在客戶端安裝 ODBC 驅(qū)動(dòng)程序,換句話說,必須安裝 Windows 的某個(gè)版本。使用這一類型要犧牲 JDBC 的平臺(tái)獨(dú)立性。另外 ODBC 驅(qū)動(dòng)程序還需具有客戶端控制權(quán)限。
? ?
類型 2 JDBC-native driver bridge
? ?JDBC
本地驅(qū)動(dòng)程序橋提供了一種 JDBC 接口,它建立在本地?cái)?shù)據(jù)庫驅(qū)動(dòng)程序的頂層,而不需要 ODBC JDBC 驅(qū)動(dòng)程序?qū)?shù)據(jù)庫的 API 從標(biāo)準(zhǔn)的 JDBC 調(diào)用轉(zhuǎn)換為本地調(diào)用,使用此類型要犧牲 JDBC 的平臺(tái)獨(dú)立性,還要求在客戶端安裝客戶端數(shù)據(jù)庫驅(qū)動(dòng)程序。
? ?
類型 3 JDBC-network bridge
? ?JDBC
網(wǎng)絡(luò)橋驅(qū)動(dòng)程序不需要客戶端數(shù)據(jù)庫驅(qū)動(dòng)程序。它使用網(wǎng)絡(luò)上的中間件服務(wù)器來存取數(shù)據(jù)庫。這種應(yīng)用使得負(fù)載均衡、連接緩沖池和數(shù)據(jù)緩存等技術(shù)的實(shí)現(xiàn)有了可能。由于第 3 種類型往往只需要相對更少的下載時(shí)間,具有平臺(tái)獨(dú)立性,且不需要在客戶端安裝數(shù)據(jù)庫驅(qū)動(dòng)程序并取得控制權(quán),所以很適合于 Internet 上的應(yīng)用。
? ?
類型 4 Pure Java driver
? ?
通過使用一個(gè)純 Java 數(shù)據(jù)庫驅(qū)動(dòng)程序來執(zhí)行數(shù)據(jù)庫的直接訪問。此類型實(shí)際上在客戶端實(shí)現(xiàn)了 2 層結(jié)構(gòu)。要在 N- 層結(jié)構(gòu)中應(yīng)用,一個(gè)更好的做法是編寫一個(gè) EJB ,讓它包含存取代碼并提供一個(gè)對客戶端具有數(shù)據(jù)庫獨(dú)立性的服務(wù)。
? ?WebLogic
服務(wù)器為一些通常的數(shù)據(jù)庫提供了 JDBC 驅(qū)動(dòng)程序,包括 Oracle Sybase Microsoft SQL Server Informix 。它也帶有一種 JDBC 驅(qū)動(dòng)程序用于 Cloudscape ,這是一種純 Java DBMS WebLogic 服務(wù)器中帶有該數(shù)據(jù)庫的評估版本。讓我們看一個(gè)實(shí)例。
? ?JDBC
實(shí)例
? ?
在這個(gè)例子中假定已在 Cloudscape 中建立了一個(gè) PhoneBook 數(shù)據(jù)庫,且包含一個(gè)表名為 CONTACT_TABLE 的表,它帶有 2 個(gè)字段: NAME PHONE 。開始時(shí)先裝載 Cloudscape JDBC driver ,并請求 driver manager 得到一個(gè)對 PhoneBook Cloudscape 數(shù)據(jù)庫的連接。通過這一連接,可構(gòu)造一個(gè) Statement 對象并用它來執(zhí)行一個(gè)簡單的 SQL 查詢。最后用循環(huán)來遍歷結(jié)果集的所有數(shù)據(jù),并用標(biāo)準(zhǔn)輸出將 NAME PHONE 字段的內(nèi)容進(jìn)行輸出。
import java.sql.*;
public class JDBCExample{
?public static void main(String args[]){
?try{
? ?Class.forName("COM.cloudscape.core.JDBCDriver");
? ?Connection conn = DriverManager.getConnection("jdbc:cloudscape honeBook");
? ?Statement stmt = conn.createStatement();
? ?String sql = "SELECT name, phone FROM CONTACT_TABLE ORDER BY name";
? ?ResultSet resultSet = stmt.executeQuery(sql);
? ?String name, phone;
? ?while (resultSet.next()){
? ? ?name = resultSet.getString(1).trim();
? ? ?phone = resultSet.getString(2).trim();
? ? ?System.out.println( name + ", " + phone );
? ?}
?}
?catch ( Exception e ){
? ?// Handle exception here
? ?e.printStackTrace();
?}
?}
}
? ?
接著我們來看一看 JDBC 是如何在企業(yè)應(yīng)用中的進(jìn)行使用。
? ?JDBC
在企業(yè)級應(yīng)用中的應(yīng)用
? ?
以上實(shí)例其實(shí)是很基本的,可能有些微不足道,它假定了一個(gè) 2 層結(jié)構(gòu)。在一個(gè)多層的企業(yè)級應(yīng)用中,更大的可能是在客戶端和一個(gè) EJB 進(jìn)行通信,該 EJB 將建立數(shù)據(jù)庫連接。為了實(shí)現(xiàn)和改進(jìn)可伸縮性和系統(tǒng)性能, WebLogic 服務(wù)器提供了對連接緩沖池 Connection pool 的支持。
? ?Connection pool
減少了建立和釋放數(shù)據(jù)庫連接的消耗。在系統(tǒng)啟動(dòng)以后即可建立這樣的緩沖池,此后如故再有對數(shù)據(jù)庫的請求, WebLogic 服務(wù)器可很簡單地從緩沖池中取出數(shù)據(jù)。數(shù)據(jù)緩沖池可在 WebLogic 服務(wù)器的 weblogic.properties 文件中進(jìn)行定義 ( 可參考 weblogic.properties 文件中的例子, WebLogic 服務(wù)器的文檔中還有更詳細(xì)的參考信息 )
? ?
在企業(yè)級應(yīng)用的另一個(gè)常見的數(shù)據(jù)庫特性是事務(wù)處理。事務(wù)是一組申明 statement ,它們必須作為同一個(gè) statement 來處理以保證數(shù)據(jù)完整性,缺省情況下 JDBC 使用 auto-commit 事務(wù)模式。這可以通過使用 Connection 類的 setAutoCommit() 方法來實(shí)現(xiàn)。

2. ? ? Java Naming and Directory Interface (JNDI)

? ?JNDI API
被用于執(zhí)行名字和目錄服務(wù)。它提供了一致的模型來存取和操作企業(yè)級的資源,如 DNS LDAP 、本地文件系統(tǒng),后者在應(yīng)用服務(wù)器中的對象。
? ?JNDI
中,在目錄結(jié)構(gòu)中的每一結(jié)點(diǎn)稱為 context 。每一個(gè) JNDI 名字都是相對于 context 的。這里沒有絕對名字的概念存在。對一個(gè)應(yīng)用來說,它可通過使用 InitialContext 類來得到其第一個(gè) context
Context ctx = new InitialContext();
? ?
應(yīng)用可通過這個(gè)初始化的 context 經(jīng)由這個(gè)目錄樹來定位它所需要的資源或?qū)ο蟆H缂僭O(shè)你在 Weblogic 服務(wù)器中展開了一個(gè) EJB 并將 home 接口綁定到名字 myApp.myEJB ,那么該 EJB 的某個(gè)客戶在取得一個(gè)初始化 context 后,可通過以下語句定位 home 接口:
MyEJBHome home = ctx.lookup( "myApp.myEJB" );
? ?
在這個(gè)例子中,一旦你有了對被請求對象的參考, EJB home 接口就可以在它上面調(diào)用方法。我們將在下面的 EJB 章節(jié)中做更多的介紹。以上關(guān)于 JNDI 的討論只是冰山之一角。如果要進(jìn)一步地在 context 中查找對象, JNDI 也提供了一些方法來進(jìn)行以下操作: 
? ?
將一個(gè)對象插入或綁定到 context ,這在你展開一個(gè) EJB 時(shí)很有效。
? ?
context 中移去對象。
? ?
列出 context 中的所有對象。
? ?
創(chuàng)建或刪除子一級的 context

3. ? ? Enterprise Java Beans (EJB)

? ?J2EE
技術(shù)之所以贏得廣泛重視的原因之一就是 EJB 。它們提供了一個(gè)框架來開發(fā)和實(shí)施分布式商務(wù)邏輯,由此很顯著地簡化了具有可伸縮性和高度復(fù)雜的企業(yè)級應(yīng)用的開發(fā)。 EJB 規(guī)范定義了 EJB 組件在何時(shí)如何與它們的容器進(jìn)行交互作用。容器負(fù)責(zé)提供公用的服務(wù),如目錄服務(wù)、事務(wù)管理、安全性、資源緩沖池及容錯(cuò)性。
? ?EJB
規(guī)范定義了 3 中基本的 bean 類型,這里先不談 Message-driven Bean
? ?Stateless session beans
:提供某種單一服務(wù)而不維持任何狀態(tài),在服務(wù)器故障發(fā)生時(shí)無法繼續(xù)存在,生命期相對較短。如它可能被用于執(zhí)行溫度轉(zhuǎn)換計(jì)算。
? ?Stateful session bean
:提供了與客戶端的會(huì)話交互,可存儲(chǔ)狀態(tài)從而代表一個(gè)客戶。典型例子是購物車。不過在服務(wù)器故障時(shí)無法繼續(xù)生存,生命期相對較短。每一個(gè)實(shí)例只用于一個(gè)單個(gè)的線程。
? ?Entity beans:
提供了一致性數(shù)據(jù)的表示,通常存放在數(shù)據(jù)庫中,在服務(wù)器故障發(fā)生后能繼續(xù)存在。多用戶情況下可使用 EJB 來表示相同的數(shù)據(jù), Entity EJB 的一個(gè)典型例子是客戶的帳號信息。
? ?
盡管有以上的區(qū)別,所有的 EJB 還是有許多的共同之處。它們都處理 home interface 。它定義了一個(gè)客戶端是如何創(chuàng)建與消亡 EJB 的。可在 bean 中對定義了客戶端方法的遠(yuǎn)程接口進(jìn)行調(diào)用; bean 類則執(zhí)行了主要的商務(wù)邏輯。
? ?
描述 EJB 的開發(fā)已經(jīng)超出了本文的范圍。但如果一個(gè) EJB 已被開發(fā)或從第三方購買,它就須在應(yīng)用服務(wù)器中進(jìn)行發(fā)布。 WebLogic Server 5.1 帶有一個(gè) EJB Deployer Tool 來協(xié)助處理 EJB 的發(fā)布。當(dāng)你使用 EJB Deployer Tool 的時(shí)候,你要定義客戶端所用的 JNDI 名字來定位 EJB Deployer Tool 將生成 wrapper 類來處理和容器的通信及在一個(gè) jar 文件中把被請求的 Java 類綁定在一起。
? ?
一旦 EJB 被發(fā)布,客戶端就可以使用它的 JNDI 名字來定位 EJB 。首先它必須得到一個(gè)到 home 接口的 reference 。然后客戶端可使用該接口,調(diào)用一個(gè) create() 方法來得到服務(wù)器上運(yùn)行的某個(gè) bean 實(shí)例的句柄;最后客戶端可以使用該句柄在 bean 中調(diào)用方法。

4. ? ? JavaServer Pages (JSPs)

? ?
我們中可能已有許多人熟悉 Microsoft ASP 技術(shù)。 JSP ASP 相對應(yīng),但更具平臺(tái)獨(dú)立性。他們被設(shè)計(jì)用以幫助 Web 內(nèi)容開發(fā)人員創(chuàng)建動(dòng)態(tài)網(wǎng)頁,且只需要相對較少的代碼。 即使 Web 設(shè)計(jì)師不懂得如何編程也可使用 JSP ,因?yàn)? JSP 應(yīng)用是很方便的。 JSP 頁面由 HTML 代碼和嵌入其中的 Java 代碼所組成。服務(wù)器在頁面被客戶端所請求后對這些 Java 代碼進(jìn)行處理,然后將生成的 HTML 頁面返回給客戶端的瀏覽器。
? ?
您可能聽說過 JHTML ,這是 JSP 前一種較老標(biāo)準(zhǔn)。 WebLogic 服務(wù)器可支持兩者。請注意在缺省狀況下, JSP WebLogic 服務(wù)器中并沒有處于有效狀態(tài)。要使之有效,你可以編輯 weblogic.properties 文件。如果 Web 服務(wù)器還沒有處于有效狀態(tài),則要先使之有效。 Servlet 的情況和 JSP 一樣。

5. ? ? Java servlets

? ?servlet
提供的功能大多與 JSP 類似,不過實(shí)現(xiàn)方式不同。 JSP 通常是大多數(shù) HTML 代碼中嵌入少量的 Java 代碼,而 servlets 全部由 Java 寫成并且生成 HTML
? ?servlet
是一種小型的 Java 程序,它擴(kuò)展了 Web 服務(wù)器的功能。作為一種服務(wù)器端應(yīng)用,當(dāng)被請求時(shí)開始執(zhí)行,這和 CGI Perl 腳本很相似。 Servlets CGI 腳本的一個(gè)很大的區(qū)別是:每一個(gè) CGI 在開始時(shí)都要求開始一個(gè)新進(jìn)程,而 servlets servlet 引擎中以分離的線程來運(yùn)行。因此其在可伸縮性上提供了很好的改進(jìn)。
? ?
在開發(fā) servlets 時(shí),常需擴(kuò)展 javax.servlet.http.HttpServlet 類,且 override 一些它的方法,其中包括:
? ?service()
:作為 dispatcher 來實(shí)現(xiàn)命令 - 定義方法
? ?doGet():
處理客戶端的 HTTP GET 請求。
? ?doPost():
進(jìn)行 HTTP POST 操作
? ?
其它的方法還包括處理不同類型的 HTTP 請求,可參考 HttpServlet API 文檔。
? ?
以上描述是標(biāo)準(zhǔn) J2EE Servlet API 的各種方法。 WebLogic 服務(wù)器提供了一個(gè)該 API 完整的實(shí)現(xiàn)途徑。一旦你開發(fā)了一個(gè) servlet ,就可以在 weblogic.properties 中加以注冊并由此可以在 WebLogic 服務(wù)器中對它進(jìn)行配置。

6. ? ? Remote Method Invocation(RMI)

? ?
在遠(yuǎn)程對象上調(diào)用一些方法,使用連續(xù)序列方式在客戶端和服務(wù)器端傳遞數(shù)據(jù)。 RMI 是一種被 EJB 使用的更下層的協(xié)議。

Java RMI簡介

? ?遠(yuǎn)程方法調(diào)用(RMI,Remote Method Invocation)是jdk1.1中引入的分布式對象軟件包,它的出現(xiàn)大大簡化了分布異構(gòu)環(huán)境中Java應(yīng)用之間的通信。

? ?要使用RMI,必須構(gòu)建四個(gè)主要的類:遠(yuǎn)程對象的本地接口、遠(yuǎn)程對象實(shí)現(xiàn)、RMI客戶機(jī)和RMI服務(wù)器。RMI服務(wù)器生成遠(yuǎn)程對象實(shí)現(xiàn)的一個(gè)實(shí)例,并用一個(gè)專有的URL注冊。RMI客戶機(jī)在遠(yuǎn)程RMI服務(wù)器上查找服務(wù)對象,并將它轉(zhuǎn)換成本地接口類型,然后像對待一個(gè)本地對象一樣使用它。

? ?下面是一個(gè)簡單的RMI實(shí)例,RMI客戶機(jī)通過RMI服務(wù)器提供的方法輸出一個(gè)語句。例子雖然很簡單,但掌握了Java RMI調(diào)用的基本原理和方法,在實(shí)現(xiàn)復(fù)雜應(yīng)用時(shí),我們需要做的也只是完善遠(yuǎn)程對象的實(shí)現(xiàn)類而已。
?
?
RMI實(shí)例分析

1.遠(yuǎn)程對象的本地接口聲明(RMIOperate.java)

? · 該類僅僅是一個(gè)接口聲明,RMI客戶機(jī)可以直接使用它,RMI服務(wù)器必須通過一個(gè)遠(yuǎn)程對象來實(shí)現(xiàn)它,并用某個(gè)專有的URL注冊它的一個(gè)實(shí)例。
? · 遠(yuǎn)程接口擴(kuò)展 java.rmi.Remote 接口。
? · 除了所有應(yīng)用程序特定的例外之外,每個(gè)方法還必須在 throws 子句中聲明 java.rmi.RemoteException (或 RemoteException 的父類)。
Hello.java
/* * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27 */ import java . rmi . * ; // RMI本地接口必須從Remote接口派生 public interface Hello extends Remote { // 接口中的具體方法聲明,注意必須聲明拋出RemoteException String sayHello( String name) throws RemoteException ; }
?
2.遠(yuǎn)程對象實(shí)現(xiàn)類

? 這個(gè)類應(yīng)實(shí)現(xiàn)RMI客戶機(jī)調(diào)用的遠(yuǎn)程服務(wù)對象的本地接口,它必須從UnicastRemoteObject繼承,構(gòu)造函數(shù)應(yīng)拋出RemoteException異常。

HelloImpl.java

              
                  
                    
                      
                        
                          
                            /*
                          
                          
                             * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27
                          
                          
                             */
                          
                          
                            import
                          
                          
                             java
                          
                          
                            .
                          
                          
                            rmi
                          
                          
                            .
                          
                          
                            *
                          
                          
                            ;
                          
                          
                            import
                          
                          
                             javax
                          
                          
                            .
                          
                          
                            rmi
                          
                          
                            .
                          
                          
                            PortableRemoteObject
                          
                          
                            ;
                          
                          
                            public
                          
                          
                            class
                          
                           HelloImpl 
                          
                            extends
                          
                           PortableRemoteObject 
                          
                            implements
                          
                           Hello { ? ?
                          
                            /* 構(gòu)造函數(shù) */
                          
                           ? ?
                          
                            public
                          
                           HelloImpl() 
                          
                            throws
                          
                          
                            RemoteException
                          
                           { ? ? ? ?
                          
                            super
                          
                          (); ? ?} ? ?
                          
                            /* 實(shí)現(xiàn)本地接口中聲明的'sayHello()'方法 */
                          
                           ? ?
                          
                            public
                          
                          
                            String
                          
                           sayHello(
                          
                            String
                          
                           message) 
                          
                            throws
                          
                          
                            RemoteException
                          
                           { ? ? ? ?
                          
                            System
                          
                          .out.println(
                          
                            "我在RMI的服務(wù)器端,客戶端正在調(diào)用'sayHello'方法。 "
                          
                          ); ? ? ? ?
                          
                            System
                          
                          .out.println(
                          
                            "Hello ?"
                          
                           + message); ? ? ? ?
                          
                            return
                          
                           message; ? ?}}
                        
                      
                    
                  
                
?
3.RMI服務(wù)器類

? 該類創(chuàng)建遠(yuǎn)程對象實(shí)現(xiàn)類HelloImpl的一個(gè)實(shí)例,然后通過一個(gè)專有的URL來注冊它。所謂注冊就是通過Java.rmi.Naming.bind()方法或Java.rmi.Naming.rebind()方法,將HelloImpl實(shí)例綁定到指定的URL上。

HelloServer.java

                
                  /*
                
                
                   * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27
                
                
                   */
                
                
                  import
                
                
                   java
                
                
                  .
                
                
                  rmi
                
                
                  .
                
                
                  *
                
                
                  ;
                
                
                  public
                
                
                  class
                
                 HelloServer {
    
                
                  public
                
                
                  static
                
                
                  void
                
                 main(
                
                  String
                
                [] args) {
        
                
                  // 在服務(wù)器端設(shè)置安全機(jī)制 ? ? ? ? 
                
                
                  /*
                
                
                   ? ? ? ? ? if (System.getSecurityManager() == null) {
                
                
                   ? ? ? ? ? ? ? System.setSecurityManager(new RMISecurityManager()); 
                
                
                   ? ? ? ? ? }
                
                
                   ? ? ? ?*/
                
                
                  try
                
                 {
            
                
                  System
                
                .out.println(
                
                  "開始 RMI Server ..."
                
                );
            
                
                  /* 創(chuàng)建遠(yuǎn)程對象的實(shí)現(xiàn)實(shí)例 */
                
                
            HelloImpl hImpl = 
                
                  new
                
                 HelloImpl();
            
                
                  System
                
                .out.println(
                
                  "將實(shí)例注冊到專有的URL "
                
                );
            
                
                  Naming
                
                .rebind(
                
                  "HelloService"
                
                , hImpl);
            
            
                
                  System
                
                .out.println(
                
                  "等待RMI客戶端調(diào)用..."
                
                );
            
                
                  System
                
                .out.println(
                
                  ""
                
                );
        } 
                
                  catch
                
                 (
                
                  Exception
                
                 e) {
            
                
                  System
                
                .out.println(
                
                  "錯(cuò)誤: "
                
                 + e);
        }
    }
}

              

請注意有關(guān) rebind 方法調(diào)用的下列參數(shù):

  • 第一個(gè)參數(shù)是 URL 格式的 java.lang.String ,表示遠(yuǎn)程對象的位置和名字。 ?

    • 需要將 myhost 的值更改為服務(wù)器名或 IP 地址。否則,如果在 URL 中省略,則主機(jī)缺省值為當(dāng)前主機(jī),而且在 URL 中無需指定協(xié)議(例如“ HelloServer ”)。 ?

    • 在 URL 中,可以選擇提供端口號:例如“/ /myhost:1234/HelloServer”。 端口缺省值為 1099。除非服務(wù)器在缺省 1099 端口上創(chuàng)建注冊服務(wù)程序,否則需要指定端口號。 ?

    ?

    ?

    ?

  • 第二個(gè)參數(shù)為從中調(diào)用遠(yuǎn)程方法的對象實(shí)現(xiàn)引用。 ?

  • RMI 運(yùn)行時(shí)將用對遠(yuǎn)程對象 stub 程序的引用代替由 hImpl 參數(shù)指定的實(shí)際遠(yuǎn)程對象引用。遠(yuǎn)程實(shí)現(xiàn)對象(如 HelloImpl 實(shí)例)將始終不離開創(chuàng)建它們的虛擬機(jī)。因此,當(dāng)客戶機(jī)在服務(wù)器的遠(yuǎn)程對象注冊服務(wù)程序中執(zhí)行查找時(shí),將返回包含該實(shí)現(xiàn)的 stub 程序的對象。 ?

?
4.RMI客戶機(jī)類

? · RMI客戶使用java.rmi.Naming.lookup()方法,在指定的遠(yuǎn)程主機(jī)上查找RMI服務(wù)對象,若找到就把它轉(zhuǎn)換成本地接口RMIOperate類型。它與CORBA不同之處在于RMI客戶機(jī)必須知道提供RMI服務(wù)主機(jī)的URL,這個(gè)URL可以通過rmi://host/path或rmi://host:port/path來指定,如果省略端口號,就默認(rèn)使用1099。
? · Java.rmi.Naming.lookup()方法可能產(chǎn)生三個(gè)異常:Java.rmi.RemoteException、Java.rmi.NotBoundException、java.net. MalformedURLException,三個(gè)異常都需要捕獲。

HelloClient.java

                
                  /*
                
                
                   * @author javamxj (CSDN Blog) 創(chuàng)建日期 2004-12-27
                
                
                   */
                
                
                  import
                
                
                   java
                
                
                  .
                
                
                  rmi
                
                
                  .
                
                
                  *
                
                
                  ;
                
                
                  public
                
                
                  class
                
                 HelloClient {
    
                
                  public
                
                
                  static
                
                
                  void
                
                 main(
                
                  String
                
                [] args) {
        
                
                  // ? 在服務(wù)器端設(shè)置安全機(jī)制 ? ? ? ? 
                
                
                  /*
                
                
                   ? ? ? ? ? if (System.getSecurityManager() == null) {
                
                
                   ? ? ? ? ? ? ? System.setSecurityManager(new RMISecurityManager()); 
                
                
                   ? ? ? ? ? }
                
                
                   ? ? ? ?*/
                
                
                  /* 默認(rèn)為本地主機(jī)和默認(rèn)端口 */
                
                
                  String
                
                 host = 
                
                  "localhost:1099"
                
                ;
        
                
                  /* 帶輸入?yún)?shù)時(shí),將host設(shè)置為指定主機(jī) */
                
                
                  if
                
                 (args.length > 0)
            host = args[0];
        
                
                  try
                
                 {
            
                
                  /* 根據(jù)指定的URL定位遠(yuǎn)程實(shí)現(xiàn)對象 */
                
                
                  /* “h”是一個(gè)標(biāo)識(shí)符,我們將用它指向?qū)崿F(xiàn)“Hello”接口的遠(yuǎn)程對象 */
                
                
            Hello h = (Hello) 
                
                  Naming
                
                .lookup(
                
                  "rmi://"
                
                 + host + 
                
                  "/HelloService"
                
                );
            
            
                
                  System
                
                .out.println(
                
                  "實(shí)現(xiàn)“Hello”接口的遠(yuǎn)程對象: "
                
                 + h);
            
                
                  System
                
                .out.println(
                
                  "我在客戶端,開始調(diào)用RMI服務(wù)器端的'sayHello'方法"
                
                );
            
                
                  System
                
                .out.println(
                
                  "歡迎, ?"
                
                 + h.sayHello(
                
                  "javamxj blog"
                
                ));
        } 
                
                  catch
                
                 (
                
                  Exception
                
                 ex) {
            
                
                  System
                
                .out.println(
                
                  "錯(cuò)誤 "
                
                 + ex);
        }
    }
}

              
?
?
5. 編譯代碼與運(yùn)行系統(tǒng):
?
? 在MS-DOS環(huán)境下,創(chuàng)建一個(gè)D:\RMISample目錄,把上面4個(gè)文件復(fù)制到這個(gè)目錄下,然后在此目錄下新建兩個(gè)文件夾:client和server(把它們分別看作是客戶端與服務(wù)端)。
?
(1).編譯所有的源代碼
? ?D:\RMISample> javac *.java

(2).生成客戶端存根和服務(wù)器框架
? ?D:\RMISample> rmic HelloImpl
? ?這將生成HelloImpl_Stub.class和HelloImpl_Skel.class。
? ( :如果需要查看這兩個(gè)類的源代碼,可以使用“ rmic -keep HelloImpl”語句)
?
(3).把Hello.class、HelloClient.class、HelloImpl_Stub.class復(fù)制到client目錄;
? ?把Hello.class、HelloServer.class、HelloImpl_Skel.class、HelloImpl_Stub.class 復(fù)制到server目錄。
?
(4).啟動(dòng)RMI注冊
? ?D:\RMISample\server>rmiregistry
? (注:我是在命令控制臺(tái)下運(yùn)行這個(gè)系統(tǒng)的,必須開啟三個(gè)控制臺(tái)窗口,一個(gè)運(yùn)行RMIRegistry,一個(gè)運(yùn)行服務(wù)器,還有一個(gè)運(yùn)行客戶端。)
?
(5).運(yùn)行和調(diào)用

● 在服務(wù)器上執(zhí)行HelloServer
?D:\RMISample\server>java HelloServer
?
● 在本地客戶機(jī)上運(yùn)行HelloClient
?D:\RMISample\client>java HelloClient
?
● 在遠(yuǎn)程客戶機(jī)上運(yùn)行HelloClient(須指明RMI服務(wù)器主機(jī)名或IP地址)
? java HelloClient ?222.222.34.34
?
運(yùn)行rmiregistry和server后的結(jié)果:
?
再運(yùn)行Client后的結(jié)果:
?
?
? 還有一點(diǎn)要注意,在上面的例子中我注釋了安全管理的代碼,如果把注釋去掉,那么需要建立一個(gè)安全策略文件,比如其文件名為 policy.txt,內(nèi)容如下:
grant {
permission java.security.AllPermission "", "";
};
這是一條簡單的安全策略,它允許任何人做任何事,對于你的更加關(guān)鍵性的應(yīng)用,你必須指定更加詳細(xì)安全策略。把這個(gè)文件復(fù)制到Client和Server目錄,然后如下運(yùn)行:
D:\RMISample\server>java -Djava.security.policy=policy.txt HelloServer
D:\RMISample\client>java -Djava.security.policy=policy.txt HelloClient



7. ? ? Java IDL/CORBA

? ?
Java IDL 的支持下,開發(fā)人員可以將 Java CORBA 集成在一起。 他們可創(chuàng)建 Java 對象并使之可在 CORBA ORB 中展開,或可創(chuàng)建 Java 類并作為和其它 ORB 一起展開的 CORBA 對象的客戶。后一種方法提供了另外一種途徑,通過它 Java 可以被用于將你的新的應(yīng)用和 legacy 系統(tǒng)相集成。

8. ? ? Java Transaction Architecture (JTA)/Java Transaction Service (JTS)

? ?JTA
定義了一種標(biāo)準(zhǔn)的 API ,應(yīng)用系統(tǒng)由此可存取各種事務(wù)監(jiān)控。
? ?JTS
CORBA OTS 事務(wù)監(jiān)控的基本的實(shí)現(xiàn), JTS 規(guī)定了事務(wù)管理器的實(shí)現(xiàn)方式。該事務(wù)管理器是在高層支持 Java Transaction API (JTA) 規(guī)范,且在較底層實(shí)現(xiàn) OMG OTS specification Java 映像。 JTS 事務(wù)管理器為應(yīng)用服務(wù)器、資源管理器、獨(dú)立的應(yīng)用及通信資源管理器提供了事務(wù)服務(wù)。

9. ? ? JavaMail and JavaBeans Activation Framework

? ?JavaMail
是用于存取郵件服務(wù)器的 API ,它提供了一套郵件服務(wù)器的抽象類。不僅支持 SMTP 服務(wù)器,也支持 IMAP 服務(wù)器。 JavaMail 利用 JavaBeans Activation Framework (JAF) 來處理 MIME- 編碼的郵件附件。 MIME 的字節(jié)流可被轉(zhuǎn)換成 Java 對象或轉(zhuǎn)換自 Java 對象。由此大多數(shù)應(yīng)用都可不需要直接使用 JAF

10. ? ? Java Messaging Service (JMS)

? ?JMS
是用于和面向消息的中間件相互通信的應(yīng)用程序接口 (API) 。它既支持點(diǎn)對點(diǎn)的域,有支持發(fā)布 / 訂閱 (publish/subscribe) 類型的域,且提供對下列類型的支持:經(jīng)認(rèn)可的消息傳遞、事務(wù)型消息的傳遞、一致性消息和具有持久性的訂閱者支持。 JMS 還提供另種方式來對您的應(yīng)用與 legacy backend 系統(tǒng)相集成。

11. ? ? Extensible Markup Language (XML)

? ?XML
是一種可用來定義其它標(biāo)記語言的語言,它被用來在不同的商務(wù)過程中共享數(shù)據(jù)。 XML 的發(fā)展和 Java 是相互獨(dú)立的,但它和 Java 具有的相同目標(biāo),即平臺(tái)獨(dú)立性。通過將 Java XML 的組合,可得到一個(gè)完美的具有平臺(tái)獨(dú)立性的解決方案。目前正有許多不同的公司在為 Java XML 的組合而努力。如果要了解更多的這方面的信息,可訪問 Sun Java-XML 頁面或 IBM developerWorks XML Zone

總結(jié)

? ?
本文介紹了建立在 J2EE 上的分布式應(yīng)用結(jié)構(gòu),且描述了 WebLogic 服務(wù)器對 J2EE 的各種支持。 然而,我們所揭示的僅是冰山之一角而已,要以一篇數(shù)千字的文章來展示 J2EE 潛在的對您的企業(yè)級應(yīng)用的影響可是很不公平的。
? ?
我們已經(jīng)關(guān)注了在您開始 J2EE 進(jìn)行工作時(shí)最有可能遇到的各類技術(shù): JDBC JNDI EJB JSP servlet 。我們也為您提供了一些尚未常見的 J2EE 技術(shù)的背景知識(shí)。不管您是一名開發(fā)人員、商務(wù)應(yīng)用分析師或項(xiàng)目經(jīng)理,都應(yīng)對 J2EE WebLogic 服務(wù)器所能提供給我們的企業(yè)級應(yīng)用所帶來的意義有一個(gè)更好的認(rèn)識(shí)。

?

參考: http://tayueerlai01.bokee.com/500929286.html

J2EE的13種核心技術(shù)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日喀则市| 松原市| 万源市| 周口市| 商河县| 九江县| 巴青县| 临潭县| 扶风县| 青神县| 茌平县| 利川市| 阿拉善左旗| 棋牌| 高清| 宁国市| 大厂| 永新县| 成安县| 南澳县| 同江市| 乐至县| 北安市| 新建县| 和硕县| 玉环县| 松江区| 铜梁县| 禄丰县| 岗巴县| 运城市| 黑龙江省| 渭南市| 南充市| 比如县| 无为县| 象山县| 金塔县| 芒康县| 克什克腾旗| 石景山区|