Java命名和目錄接口_第1頁
Java命名和目錄接口_第2頁
Java命名和目錄接口_第3頁
Java命名和目錄接口_第4頁
Java命名和目錄接口_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、Java命名和目錄接口(Java Naming and Directory Interface ,JNDI)是用于從Java應(yīng)用程序中訪問名稱和目錄服務(wù)的一組API。命名服務(wù)即將名稱與對象相關(guān)聯(lián),以便能通過相應(yīng)名稱訪問這些對象。而目錄服務(wù)即其對象具有屬性及名稱的命名服務(wù)。命名或目錄服務(wù)允許您集中管理共享信息的存儲(chǔ),這在網(wǎng)絡(luò)應(yīng)用程序中很重要,因?yàn)樗梢允惯@類應(yīng)用程序更加一致和易于管理。例如,可以將打印機(jī)配置存儲(chǔ)在目錄服務(wù)中,這樣所有與打印機(jī)相關(guān)的應(yīng)用程序都能夠使用它。本文是一份代碼密集型的快速入門指南,讓您開始了解和使用JNDI。它: § 提供對JNDI的綜述。 § 描述JN

2、DI的特性。 § 提供使用JNDI開發(fā)應(yīng)用程序過程中的體驗(yàn)。 § 說明如何使用JNDI訪問 LDAP 服務(wù)器,比如Sun ONE Directory Server 。 § 說明如何使用 JNDI 訪問J2EE 服務(wù)。 § 提供示例代碼,您可以對其進(jìn)行修改,以用于您自己的應(yīng)用程序。 JNDI綜述我們所有人每天都在不自知的情況下使用命名服務(wù)。例如,當(dāng)您在瀏覽器中輸入U(xiǎn)RL 時(shí),域名系統(tǒng)(Domain Name System ,DNS)將這個(gè)以符號(hào)表示的URL轉(zhuǎn)換為一個(gè)通信標(biāo)識(shí)符(IP地址)。在命名系統(tǒng)中,對象的范圍可以從位于DNS記錄中的名稱變動(dòng)到應(yīng)用程序服

3、務(wù)器中的企業(yè)JavaBeans組件(Enterprise JavaBeans Components ,EJBs),還可以到輕量級(jí)目錄訪問協(xié)議(Lightweight Directory Access Protocol ,LDAP)中的用戶配置文件。目錄服務(wù)是命名服務(wù)的自然擴(kuò)展。二者的關(guān)鍵區(qū)別在于,目錄服務(wù)允許屬性(比如用戶的電子郵件地址)與對象相關(guān)聯(lián),而命名服務(wù)則不然。這樣,使用目錄服務(wù)時(shí),您可以基于對象的屬性來搜索它們。JNDI允許您訪問文件系統(tǒng)中的文件,定位遠(yuǎn)程RMI注冊表中的對象,訪問諸如LDAP這樣的目錄服務(wù),并定位網(wǎng)絡(luò)上的EJB。很多應(yīng)用程序選擇使用JNDI都可以收到良好的效果,比如

4、LDAP客戶端、應(yīng)用程序啟動(dòng)器、類瀏覽器、網(wǎng)絡(luò)管理實(shí)用工具,或者甚至是地址簿。JNDI架構(gòu)JNDI架構(gòu)提供了一個(gè)標(biāo)準(zhǔn)的、與命名系統(tǒng)無關(guān)的API,這個(gè)API構(gòu)建在特定于命名系統(tǒng)的驅(qū)動(dòng)程序之上。這一層幫助把應(yīng)用程序和實(shí)際的數(shù)據(jù)源隔離開來,因此無論應(yīng)用程序是訪問LDAP、RMI、DNS還是其他的目錄服務(wù),這都沒有關(guān)系。換句話說,JNDI與任何特定的目錄服務(wù)實(shí)現(xiàn)無關(guān),您可以使用任何目錄,只要您擁有相應(yīng)的服務(wù)提供程序接口(或驅(qū)動(dòng)程序)即可,如圖1所示。圖1: JNDI架構(gòu)注意,關(guān)于JNDI有一點(diǎn)很重要,即它同時(shí)提供應(yīng)用程序編程接口(Application Programming Interface ,A

5、PI)和服務(wù)提供程序接口(Service Provider Interface ,SPI)。這樣做的實(shí)際意義在于,對于您的與命名或目錄服務(wù)交互的應(yīng)用程序來說,必須存在用于該服務(wù)的一個(gè)JNDI服務(wù)提供程序,這便是JNDI SPI發(fā)揮作用的舞臺(tái)。一個(gè)服務(wù)提供程序基本上就是一組類,這些類針對特定的命名和目錄服務(wù)實(shí)現(xiàn)了各種JNDI接口這與JDBC驅(qū)動(dòng)程序針對特定的數(shù)據(jù)系統(tǒng)實(shí)現(xiàn)各種JDBC接口極為相似。作為一名應(yīng)用程序開發(fā)人員,您不需要擔(dān)心JNDI SPI.。您只需確保,您為每個(gè)想使用的命名或目錄服務(wù)提供了一個(gè)服務(wù)提供程序。J2SE和JNDIJNDI被包含在Java 2 SDK 1.3 及其更新版本中。

6、它還可以用作JDK 1.1和1.2的一個(gè)標(biāo)準(zhǔn)擴(kuò)展。 Java 2 SDK 1.4.x的最新版本進(jìn)行了改進(jìn),將以下命名/目錄服務(wù)提供程序包括進(jìn)來: § 輕量級(jí)目錄訪問協(xié)議(Lightweight Directory Access Protocol,LDAP) 服務(wù)提供程序。 § 公共對象請求代理架構(gòu)(Common Object Request Broker Architecture ,CORBA)公共對象服務(wù)(Common Object Services ,COS)命名服務(wù)提供程序。 § Java遠(yuǎn)程方法調(diào)用( Remote Method Invocation ,R

7、MI)注冊表服務(wù)提供程序。 § 域名系統(tǒng)( Domain Name System ,DNS) 服務(wù)提供程序。 有關(guān)服務(wù)提供程序的更多內(nèi)容在這里可以下載一系列服務(wù)提供程序。Windows注冊表JNDI 提供程序(來自)可能會(huì)引起您特別的興趣,因?yàn)樗试S您訪問Windows XP/2000/NT/Me/9x上的注冊表。此外,還可以下載JNDI/LDAP Bootster Pack。這個(gè)增強(qiáng)補(bǔ)丁包含對流行的LDAP控件和擴(kuò)展的支持。它代替了與LDAP 1.2.1服務(wù)提供程序捆綁在一起的增強(qiáng)補(bǔ)丁。參見 Controls and Extensions 以獲得更多信息。另一個(gè)要考察的有趣的服務(wù)提

8、供程序是Sun的Directory Services Markup Language (DSML) v2.0提供程序。 DSML的目標(biāo)是將目錄服務(wù)與XML連接起來 JNDI APIJNDI API 包括5個(gè)包: § javax.naming: 包含用于訪問命名服務(wù)的類和接口。例如,它定義了Context接口,該接口是執(zhí)行查找時(shí)命名服務(wù)的入口點(diǎn)。 § javax.naming.directory:擴(kuò)展命名包以提供用于訪問目錄服務(wù)的類和接口。例如,它增加了新的屬性類,提供代表一個(gè)目錄上下文的DirContext 接口,并且定義了用于檢查和更新與目錄對象相關(guān)的屬性的方法。 

9、67; javax.naming.event: 當(dāng)訪問命名和目錄服務(wù)時(shí),為事件通知提供支持。例如,它定義了一個(gè)NamingEvent類,用于表示由命名/目錄服務(wù)生成的事件,以及一個(gè)監(jiān)視NamingEvents 類的, NamingListener 接口。 § javax.naming.ldap: 這個(gè)包為LDAP 版本 3 擴(kuò)展操作和空間提供特定的支持,而普通的javax.naming.directory 包沒有提供這些支持。 § javax.naming.spi: 這個(gè)包提供方法以動(dòng)態(tài)插入對通過javax.naming及其相關(guān)包訪問命名和目錄服務(wù)的支持。只有那些對創(chuàng)建服務(wù)

10、提供程序有著濃厚興趣的開發(fā)人員才應(yīng)該對這個(gè)包感興趣。 JNDI 上下文承前所述,命名服務(wù)是將名稱與對象相關(guān)聯(lián)。這種關(guān)聯(lián)被稱為綁定。一組這樣的綁定被稱為上下文,它提供返回對象的分解或查找操作。其他操作還可能包括綁定與解除綁定名稱,以及列出被綁定的名稱。注意,可以將一個(gè)上下文對象中的名稱綁定到具有同樣命名慣例的另一個(gè)上下文對象上。這被稱為子上下文。例如,如果UNIX目錄/home 是一個(gè)上下文,那么名稱與其相關(guān)的目錄便是子上下文。例如,/home/guests.,這里的guests 便是 home的一個(gè)子上下文。在JNDI中,上下文是使用javax.naming.Context 接口來表示的,而這

11、個(gè)接口也正是與命名服務(wù)進(jìn)行交互的主要接口。Context (或稍后將要討論的DirContext)接口中的每個(gè)命名方法都有兩種重載的形式: § lookup(String name): 接受一個(gè)字符串名稱。 § lookup(javax.naming.Name): 接受一個(gè)結(jié)構(gòu)化的名稱,比如CompositeName (一個(gè)跨越多個(gè)命名系統(tǒng)的名稱)或 CompondName (一個(gè)位于單個(gè)命名系統(tǒng)中的名稱);二者均實(shí)現(xiàn)了Name 接口。下面是一個(gè)復(fù)合名稱的例子: cn=mydir,cn=Q Mahmoud,ou=People,還有一個(gè)組合名稱的例子: cn=mydir,cn

12、=Q Mahmoud,ou=People/myfiles/max.txt (這里的myfiles/max.txt 是代表第二部分的一個(gè)文件名)。 javax.naming.InitialContext 是一個(gè)實(shí)現(xiàn)了 Context接口的類。使用這個(gè)類作為您到命名服務(wù)的入口點(diǎn)。要?jiǎng)?chuàng)建一個(gè)InitialContext 對象,構(gòu)造器需要采用一組屬性,形式為java.util.Hashtable 或其子類之一,比如Properties.。下面是一個(gè)例子: Hashtable env = new Hashtable();/ select a service provider factoryenv.put

13、(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContext");/ create the initial contextContext contxt = new InitialContext(env);INITIAL_CONTEXT_FACTORY 指定JNDI服務(wù)提供程序中工廠類的名稱。該工廠負(fù)責(zé)為其服務(wù)創(chuàng)建一個(gè)合適的InitialContext 對象。在上面的代碼片斷中,指定了用于文件系統(tǒng)服務(wù)提供程序的一個(gè)工廠類。表1列出了用于所支持的服務(wù)提供程序的工廠類。注意,用于文件系統(tǒng)服務(wù)提供程序的

14、工廠類需要從Sun Microsystems單獨(dú)下載,它并沒有與J2SE 1.4.x一起發(fā)行。表 1: Context.INITIAL_CONTEXT_FACTORY的值名稱服務(wù)提供程序工廠文件系統(tǒng)com.sun.jndi.fscontext.RefFSContextFactoryLDAPcom.sun.jndi.ldap.LdapCtxFactoryRMIcom.sun.jndi.rmi.registry.RegistryContextFactoryCORBAcom.sun.jndi.cosnaming.CNCtxFactoryDNScom.sun.jndi.dns.DnsContextFa

15、ctory要通過來自命名或目錄服務(wù)的名稱檢索或解析(查找)一個(gè)對象,使用Context: Object obj = contxt.lookup(name)的lookup方法。lookup 方法返回一個(gè)對象,該對象代表您想要查找的上下文的子上下文。一個(gè)命名的例子現(xiàn)在,讓我們看一看一個(gè)使用命名服務(wù)的例子。在這個(gè)例子中,我們編寫了一個(gè)簡單的程序,用于查找一個(gè)其名稱被當(dāng)作命令行參數(shù)傳入的對象。在這里,我們將使用一個(gè)用于文件系統(tǒng)的服務(wù)提供程序,而且因此,我們提供作為參數(shù)的名稱必須是一個(gè)文件名。示例代碼1中給出了相應(yīng)代碼。示例代碼 1: Resolve.java import javax.naming.C

16、ontext;import javax.naming.InitialContext;import javax.naming.NamingException;import java.util.Hashtable;public class Resolve    public static void main(String argv)       / The user should provide a file to lookup      if (argv.length != 1

17、)          System.err.println("Usage: java Resolve ");         System.exit(-1);            String name = argv0;      / Here we use the

18、file system service provider      Hashtable env = new Hashtable();      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");      try        

19、0; / Create the initial context         Context ctx = new InitialContext(env);         / Look up an object         Object obj = ctx.lookup(name);      

20、;   / Print it out         System.out.println(name + " is bound to: " + obj);         / Close the context         ctx.close();      cat

21、ch (NamingException e)          System.err.println("Problem looking up " + name + ": " + e);         在這里,我假定您使用的是Java 2SDK 1.4.x,它附帶有幾個(gè)服務(wù)提供程序(上面已經(jīng)列出)。這個(gè)應(yīng)用程序要使用文件系統(tǒng)服務(wù)提供程序 ,而在默認(rèn)情況下,文件系統(tǒng)服務(wù)提供程序并未安裝。因此,您需要下載并安裝

22、它。另一方面,如果您運(yùn)行這個(gè)程序,而服務(wù)提供程序卻還沒有被安裝,您將得到一個(gè)NoInitialContextException,意指無法找到服務(wù)提供程序工廠類,因此不能初始化這個(gè)類。接著,您需要在您的classpath中包括fscontext.jar 和providerutil.jar或者像我一樣,您可以簡單地將這兩個(gè)文件拷貝至JAVA_HOMEjrelibext,這里的 JAVA_HOME 是指您的Java 2SDK安裝的根目錄。要測試這個(gè)應(yīng)用程序: 1.         確保您已經(jīng)下載并安裝了文件系統(tǒng)服務(wù)提供程

23、序(正如上一段所講的那樣),因?yàn)檫@個(gè)服務(wù)提供程序并沒有與J2SE 1.4.x一起提供。2.         拷貝代碼并將其粘貼到文件中,并將文件命名為Resolve.java。3.         使用javac 編譯 Resolve.java 。4.         使用java 解釋器運(yùn)行應(yīng)用程序。下面是一次示范運(yùn)行: prompt> java R

24、esolve classesclasses is bound to: com.sun.jndi.fscontext.FSContextf62373如果您提供的名稱是一個(gè)文件名,您將看到如下結(jié)果: prompt> java Resolve classesResolve.java classesResolve.java is bound to: C:classesResolve.java列出文件目錄的內(nèi)容 現(xiàn)在,讓我們看一看如何使用其他JNDI API列出一個(gè)文件目錄的內(nèi)容。我們假定,您想讓用戶能夠使用file:/這樣的URL 來指定命令行參數(shù)。在這種情況下,您要設(shè)置一個(gè)新的屬性PROVID

25、ER_URL,如示例代碼2所示。Context 的listBindings 方法返回一個(gè) NamingEnumeration對象,可以通過使用一個(gè)while 循環(huán)來迭代這個(gè)對象,如示例代碼 2所示。示例代碼 2 Resolve2.java import javax.naming.Binding;import javax.naming.NamingEnumeration;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import java.uti

26、l.Hashtable;public class Resolve2    public static void main(String argv)       / The user should provide a file to lookup      if (argv.length != 1)          System.err.println("Usage: java Reso

27、lve2 ");         System.exit(-1);            / Here we use the file system service provider      Hashtable env = new Hashtable();      env.put(Context.INIT

28、IAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.FSContextFactory");      env.put(Context.PROVIDER_URL, argv0);      try          / Create the initial context       

29、0; Context ctx = new InitialContext(env);         NamingEnumeration ne = ctx.listBindings("");         while(ne.hasMore()            Binding b = (Binding) ne.ne

30、xt();           System.out.println(b.getName() + " " + b.getObject();                  / close the context         ctx.c

31、lose();      catch (NamingException e)          System.err.println("Problem looking up " + argv0 + ": " + e);         要測試這個(gè)應(yīng)用程序,遵照與上一個(gè)例子同樣的編輯和運(yùn)行步驟即可。下面是一次示范運(yùn)行: prompt>: java Res

32、olve2 file:/uddifig1.gif C:uddifig1.giffig2.gif C:uddifig2.giffig3.gif C:uddifig3.giffig4.gif C:uddifig4.giffig5.gif C:uddifig5.gifimpl.txt C:uddiimpl.txt目錄服務(wù)承前所述,目錄服務(wù)便是其對象具有屬性及名稱的命名服務(wù)。具有屬性和名稱的對象被稱為目錄入口。應(yīng)用程序可以使用目錄服務(wù)存儲(chǔ)和檢索目錄對象的屬性。它甚至可以被用于對象存儲(chǔ)。LDAP輕量級(jí)目錄訪問協(xié)議(LDAP)來源于X.500 協(xié)議(由位于Ann Arbor的密歇根大學(xué)開發(fā)),是一個(gè)用于訪

33、問和管理目錄服務(wù)的協(xié)議;它定義了客戶端應(yīng)該如何訪問存儲(chǔ)在服務(wù)器上的數(shù)據(jù),但沒有定義應(yīng)該如何存儲(chǔ)數(shù)據(jù)。LDAP目錄由帶有描述性信息的入口組成,這些描述性信息描述了人(例如,姓名、電話號(hào)碼、電子郵件地址,等等)或網(wǎng)絡(luò)資源(比如打印機(jī)、傳真機(jī)之類的)。這類描述性信息被存儲(chǔ)在一個(gè)入口的屬性中,入口的每個(gè)屬性均描述了一種特定類型的信息。下面給出一個(gè)例子,內(nèi)容是用于描述一個(gè)人的屬性: cn: Qusay H. Mahmoudmail: qmahmoudtelephoneNumber: 123-4567LDAP 目錄服務(wù)可以用于基于屬性查找某個(gè)人的電話號(hào)碼或電子郵件地址。表2列出了一些常見的LDAP 屬性:

34、 表 2: 一些常見的 LDAP 屬性屬性意義o組織cn常用名 sn姓uid用戶idmail電子郵件地址c國家LDAP名稱是一個(gè) (名稱,值) 對的序列,比如姓名、組織、國家。cn=Qusay Mahmoud, o=, c=Canadajavax.naming.directory.DirContext是一個(gè)JNDI的目錄服務(wù)接口,它擴(kuò)展了javax.naming.Context。它提供的方法有: § search: 搜索匹配目錄入口的目錄,并比較一個(gè)目錄入口和一組屬性。 § bind 和createSubcontext: 添加一個(gè)新的目錄入口。 § modifyA

35、ttributes: 修改一個(gè)目錄入口的特定屬性。rename 方法可以用于修改入口名稱本身。 § unbind 和destroySubcontext: 刪除一個(gè)特定的目錄入口。 § close: 結(jié)束與一臺(tái)LDAP服務(wù)器的會(huì)話。 使用JNDI 進(jìn)行LDAP編程要操作一臺(tái)LDAP 服務(wù)器(比如Sun ONE Directory Server)中的對象,您必須首先連接到該服務(wù)器;您可能還需要使您自己通過服務(wù)器的身份驗(yàn)證。要連接到服務(wù)器,您可以從DirContext 接口獲得對一個(gè)對象的引用。使用InitialDirContext 類可以做到這一點(diǎn),而該類需要一個(gè) Hashta

36、ble。下面的代碼片斷可以使用戶通過一臺(tái)LDAP服務(wù)器的身份驗(yàn)證,并連接到該服務(wù)器上。注意,這里使用的是簡單的身份驗(yàn)證。簡單身份驗(yàn)證包括把用戶的完全限定的DN和用戶的明文口令發(fā)送給LDAP 服務(wù)器。要避免暴露明文口令,使用帶有加密通道的SSL機(jī)制,如果您的LDAP服務(wù)器支持這種機(jī)制的話。想要了解關(guān)于身份驗(yàn)證模式的更多信息,請參見 JNDI Tutorial。Hashtable env = new Hashtable();env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");/

37、 specify where the ldap server is runningenv.put(Context.PROVIDER_URL, "ldap:/GH308C-N-MAHMOUD.:61596");env.put(Context.SECURITY_AUTHENTICATION, "simple");env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");env.put(Context.SECURITY_CREDENTIALS, "p

38、assword");/ Create the initial directory contextDirContext ctx = new InitialDirContext(env);連接到LDAP 服務(wù)器上之后,您可以在LDAP服務(wù)器上添加新的入口、或者修改、刪除、搜索一個(gè)入口。下面的代碼片斷說明了如何添加或存儲(chǔ)一個(gè)新的入口。注意:要存儲(chǔ)一個(gè)對象,您需要使用Java Schema裝載它,而 Java Schema并沒有在目錄服務(wù)器上被預(yù)配置。想要了解關(guān)于此點(diǎn)的更多信息,請參見JNDI指南中的Java Objects and the Directory 部分。SomeObject O

39、bj = new SomeObjct("param1", "param2", "param3");ctx.bind("cn=myobject", obj);您可以使用lookup 方法查找一個(gè)對象,如下:SomeObject obj = (SomeObject) ctx.lookup("cn=myobject");示例代碼3 給出了一個(gè)如何檢索命名對象的屬性的例子。正如您所看到的那樣,用于選擇工廠類的代碼與前面相同。我們使用InitialDirContext 類創(chuàng)建了一個(gè)目錄上下文DirCont

40、ext,getAttributes 方法用于返回對象的屬性,而最后,get方法找到了姓并打印之。相當(dāng)直觀,是不是? 示例代碼 3: GetAttrib.java import javax.naming.Context;import javax.naming.directory.InitialDirContext;import javax.naming.directory.DirContext;import javax.naming.directory.Attributes;import javax.naming.NamingException;import java.util.Hashtabl

41、e;class GetAttrib    public static void main(String argv)       Hashtable env = new Hashtable();      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");      / specify where the

42、ldap server is running      env.put(Context.PROVIDER_URL, "ldap:/localhost:389/o=,c=Canada");      / use simple authenticate to authenticate the user      env.put(Context.SECURITY_AUTHENTICATION, "simple")

43、;      env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");      env.put(Context.SECURITY_CREDENTIALS, "password");      try          / Create the initial di

44、rectory context         DirContext ctx = new InitialDirContext(env);         / Ask for all attributes of the object         Attributes attrs = ctx.getAttributes("cn=Qusay Mahm

45、oud");         / Find the surname ("sn") attribute of this object and print it         System.out.println("Last Name: " + attrs.get("sn").get();       

46、;  / Close the context         ctx.close();      catch (NamingException e)          System.err.println("Problem getting attribute: " + e);        

47、; JNDI提供用于進(jìn)行基本和高級(jí)(使用過濾器)搜索的 API 。例如,使用一組入口必須具有的屬性,以及要在其中執(zhí)行搜索的目標(biāo)上下文,便可以執(zhí)行一次簡單的搜索。下面的代碼片斷說明了如何在一棵子樹中搜索一個(gè)具有uid=qmahmoud 屬性的入口。使用過濾器的高級(jí)搜索不在本文的討論范圍之內(nèi)。/ ignore attribute name caseAttributes matchattribs = new BasicAttributes(true);matchattribs.put(new BasicAttribute("uid", "qmahmoud");

48、/ search for objects with those matching attributesNamingEnumeration answer = ctx.search("ou=People,o=", matchattribs);while (answer.hasMore()   SearchResult sr = (SearchResult)answer.next();  / print the results you need想要了解使用JNDI編寫LDAP 客戶端方面的更多信息,請參見Tips for LDAP Users。JNDI 的CO

49、RBA COS命名服務(wù)提供程序 CORBA 公共對象服務(wù) (COS) 名稱服務(wù)器用于存儲(chǔ)CORBA對象引用。您可以使用COS命名包(org.omg.CORBA.CosNaming)在CORBA 應(yīng)用程序中訪問它。JNDI COS命名服務(wù)提供程序基于COS命名包實(shí)現(xiàn)了javax.naming.Context 接口,這樣CORBA 應(yīng)用程序就能夠使用JNDI訪問 COS 名稱服務(wù)器。因此,使用 JNDI 的CORBA 應(yīng)用程序具有一個(gè)用于訪問所有命名和目錄服務(wù)的接口。這使得CORBA應(yīng)用程序能夠使用像LDAP這樣的分布式企業(yè)級(jí)服務(wù)來存儲(chǔ)對象引用。要選擇COS 命名服務(wù)提供程序,使用: env.pu

50、t(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.cosnaming.CNCtxFactory");要轉(zhuǎn)換您的CORBA 應(yīng)用程序以使用JNDI,考慮AddServer.java 和AddClient.java,它們在另一篇文章中有更加詳細(xì)的描述。1.         在客戶端和服務(wù)器中均使用javax.naming,將: import org.omg.CosNaming.*;import org.omg.CosNaming.NamingConte

51、xtPackage.*;替換為: import javax.naming.*;2.         在客戶端和服務(wù)器中使用InitialContext 代替 NameService : 將: org.omg.CORBA.Object objRef =        orb.resolve_initial_references("NameService");NamingContextExt ncRef =  

52、      NamingContextExtHelper.narrow(objRef);替換為: Hashtable env = new Hashtable();env.put("java.naming.corba.orb", orb);Context ctx = new InitialContext(env);3.         使用lookup 代替resolve: 將: String name = "Add"Add h

53、ref = AddHelper.narrow(ncRef.resolve_str(name);替換為: Add href = AddHelper.narrow(org.omg.CORBA.Object)ctx.lookup("Add");JNDI 的RMI 注冊表服務(wù)提供程序 RMI 注冊表服務(wù)提供程序允許JNDI 應(yīng)用程序訪問使用RMI注冊表注冊的遠(yuǎn)程對象。已知注冊表所在的位置之后,提供程序使用綁定為注冊在注冊表中的對象創(chuàng)建一個(gè)命名上下文。接下來,這個(gè)上下文可以被綁定到另一個(gè)JNDI可訪問的命名空間中,比如LDAP。這項(xiàng)新功能包含了java.rmi.Naming 類提供的

54、功能。這樣使用RMI的主要優(yōu)點(diǎn)是,客戶端不再需要知道RMI注冊表運(yùn)行之處的主機(jī)名和端口號(hào);它與位置無關(guān)。下面的代碼片斷說明了如何將JNDI 與 RMI一起使用: / select the registry service provider as the initial contextenv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");/ specify where the registry is runningenv.put(Context.

55、PROVIDER_URL, "rmi:/server:1099");/ create an initial context that accesses the registryContext ctx = new InitialContext(env);/ now, the names stored in registry can be listedNamingEnumeration enum = ctx.list("");/ bind the registry context into LDAP directoryContext ldapctx = (C

56、ontext)ctx.lookup("ldap:/server:port/o=comp,c=ca");ldapctx.bind("cn=rmi", ctx);JNDI 的DNS 服務(wù)提供程序 DNS服務(wù)提供程序使得基于JNDI的應(yīng)用程序能夠訪問存儲(chǔ)在DNS中的信息。DNS服務(wù)提供程序?qū)NS命名空間呈現(xiàn)為JNDI 目錄上下文的一棵樹,而將DNS 資源記錄呈現(xiàn)為JNDI 屬性。示例代碼 4 演示了如何使用DNS 服務(wù)提供程序檢索環(huán)境和IP地址(A記錄)的信息。示例代碼 4: TestDNS.java import javax.naming.*;import

57、 com.sun.jndi.dns.*;import java.util.Hashtable;public class TestDNS    public static void main(String argv)       Name cn = null;      String name = argv0;      Hashtable env = new Hashtable();   

58、0;  env.put(Context.INITIAL_CONTEXT_FACTORY,                     "com.sun.jndi.dns.DnsContextFactory");      env.put(Context.PROVIDER_URL, "dns:/IP for DNS Serv

59、er/");      try          / Create the initial context         Context ctx = new InitialContext(env);         / print the fully qualified name (.) 

60、;        System.out.println("Name in namespace: "+ctx.getNameInNamespace();         / retrieve the parser associated with the named context         NameParser np = ctx.getName

61、Parser(ctx.getNameInNamespace();          if (argv.length != 1)             System.out.println("Usage: java TestDNS ");            Syst

62、em.exit(-1);                  / parse the name into its components and print them         cn = np.parse(name);         System.out.println(&q

63、uot;Name is: "+cn.toString();         System.out.println("The parsed name has "+cn.size()+" components:");         for (int i=0; i<cn.size(); i+)        

64、;    System.out.println(cn.get(i);                  System.out.print("Trying to lookup ");         / get the prefix (domain) and suffix (hostname) 

65、60;       Name domain = cn.getPrefix(cn.size()-1);         Name host = cn.getSuffix(cn.size()-1);         System.out.println("DNS Host: "+host+" Domain: "+domain); &

66、#160;       / retrieve the named object         Object obj = ctx.lookup(domain);         System.out.println(domain.toString()+" is bound to: "+obj);     &#

67、160;   / retrieve and print the environment in effect         System.out.println("Domain properties: "+ (Context)obj).getEnvironment();         / retrieve and print the IP address (the DNS A records)&

68、#160;        System.out.println("IP for: "+cn+ " is: "+                            (DnsContext)obj).getAttribu

69、tes(host, new String"A");         / we're done so close the context         ctx.close();      catch (NamingException e)          System.err.p

70、rintln("Problem looking up " + cn + ": " + e);         在您運(yùn)行這個(gè)應(yīng)用程序之前,確保您指定了DNS服務(wù)器的IP地址。下面是一次示范運(yùn)行: prompt> java TestDNS Name in namespace: .Name is: The parsed name has 4 components:edumitaiprepTrying to lookup DNS

71、 Host: prep Domain: is bound to: com.sun.jndi.dns.DnsContextb89838Domain properties: vider.url=dns:/IP for DNS Server/, java.naming.factory.initial=com.sun.jndi.dns.DnsContextFactoryIP for: is: a=A: JNDI 和J2EEJNDI 是J2EE平臺(tái)的標(biāo)準(zhǔn)服務(wù)API之一。包含它的

72、目的是為應(yīng)用程序組件提供一個(gè)標(biāo)準(zhǔn)的API,用于引用資源和其他應(yīng)用程序組件。J2EE還定義了一種標(biāo)準(zhǔn)的命名策略(邏輯和真實(shí)的名稱),以和 JNDI一起使用,這樣就可以采用一種與部署環(huán)境無關(guān)的方式編寫應(yīng)用程序。您可以引用 J2EE服務(wù),具體方法是根據(jù)其邏輯名稱在目錄中查找它們。為了實(shí)現(xiàn)這一點(diǎn),每個(gè)符合 J2EE規(guī)范的系統(tǒng)均提供了一個(gè)稱為環(huán)境的JNDI 服務(wù),該環(huán)境包括: § 環(huán)境變量 § EJB 引用 § 資源工廠引用 注意:在這里,我只討論環(huán)境變量。想要了解EJB引用和資源工廠引用方面的更多信息,請參見這篇文章 。環(huán)境變量應(yīng)用程序組件的命名環(huán)境允許您定制應(yīng)用程序組件

73、,而不需要訪問或修改組件的源代碼。每個(gè)應(yīng)用程序組件定義它自己的環(huán)境入口的集合。同一個(gè)容器中,一個(gè)應(yīng)用程序組件的所有實(shí)例共享同一個(gè)入口。注意,不允許應(yīng)用程序組件實(shí)例在運(yùn)行時(shí)修改環(huán)境。聲明環(huán)境變量應(yīng)用程序組件提供程序必須聲明從應(yīng)用程序的組件代碼訪問的所有環(huán)境入口。它們是在部署描述器(例如Tomcat中的web.xml)中通過使用<env-entry> 標(biāo)簽來聲明的. <env-entry> 標(biāo)簽的元素有:§ <description>:環(huán)境入口的可選描述。 § <env-entry-name>: 環(huán)境入口名。 § <env-entry-type>:期望的環(huán)境變量類型。它可以是以下 Java 類型之一: Boo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論