一、內(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é)議。
【
? ?遠(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)類而已。
1.遠(yuǎn)程對象的本地接口聲明(RMIOperate.java)
? · 該類僅僅是一個(gè)接口聲明,RMI客戶機(jī)可以直接使用它,RMI服務(wù)器必須通過一個(gè)遠(yuǎn)程對象來實(shí)現(xiàn)它,并用某個(gè)專有的URL注冊它的一個(gè)實(shí)例。
java.rmi.Remote
接口。
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
; }
|
? 這個(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; ? ?}}
|
? 該類創(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 程序的對象。 ?
? · 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。
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); } } } |
(2).生成客戶端存根和服務(wù)器框架
? ?D:\RMISample\server>rmiregistry
● 在服務(wù)器上執(zhí)行HelloServer
?D:\RMISample\server>java HelloServer
?D:\RMISample\client>java HelloClient
? java HelloClient ?222.222.34.34
permission java.security.AllPermission "", "";
};
】
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í)。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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