隨筆-128  評論-55  文章-5  trackbacks-0
            基于JNDI的應(yīng)用開發(fā)

              JNDI(The Java Naming and Directory Interface,Java命名和目錄接口)是一組在Java應(yīng)用中訪問命名和目錄服務(wù)的API.命名服務(wù)將名稱和對象聯(lián)系起來,使得我們可以用名稱訪問對象。目錄服務(wù)是一種命名服務(wù),在這種服務(wù)里,對象不但有名稱,還有屬性。

              命名或目錄服務(wù)使你可以集中存儲共有信息,這一點在網(wǎng)絡(luò)應(yīng)用中是重要的,因為這使得這樣的應(yīng)用更協(xié)調(diào)、更容易管理。例如,可以將打印機設(shè)置存儲在目錄服務(wù)中,以便被與打印機有關(guān)的應(yīng)用使用。


            JNDI概述

              我們大家每天都不知不覺地使用了命名服務(wù)。例如,當(dāng)你在web瀏覽器輸入URL,http://java.sun.com時,DNS(Domain Name System,域名系統(tǒng))將這個符號URL名轉(zhuǎn)換成通訊標(biāo)識(IP地址)。命名系統(tǒng)中的對象可以是DNS記錄中的名稱、應(yīng)用服務(wù)器中的EJB組件(Enterprise JavaBeans Component)、LDAP(Lightweight Directory Access Protocol)中的用戶Profile.

              目錄服務(wù)是命名服務(wù)的自然擴展。兩者之間的關(guān)鍵差別是目錄服務(wù)中對象可以有屬性(例如,用戶有email地址),而命名服務(wù)中對象沒有屬性。因此,在目錄服務(wù)中,你可以根據(jù)屬性搜索對象。JNDI允許你訪問文件系統(tǒng)中的文件,定位遠(yuǎn)程RMI注冊的對象,訪問象LDAP這樣的目錄服務(wù),定位網(wǎng)絡(luò)上的EJB組件。

              對于象LDAP 客戶端、應(yīng)用launcher、類瀏覽器、網(wǎng)絡(luò)管理實用程序,甚至地址薄這樣的應(yīng)用來說,JNDI是一個很好的選擇。

              JNDI架構(gòu)

              JNDI架構(gòu)提供了一組標(biāo)準(zhǔn)的獨立于命名系統(tǒng)的API,這些API構(gòu)建在與命名系統(tǒng)有關(guān)的驅(qū)動之上。這一層有助于將應(yīng)用與實際數(shù)據(jù)源分離,因此不管應(yīng)用訪問的是LDAP、RMI、DNS、還是其他的目錄服務(wù)。換句話說,JNDI獨立于目錄服務(wù)的具體實現(xiàn),只要你有目錄的服務(wù)提供接口(或驅(qū)動),你就可以使用目錄。如圖1所示。 圖1:JNDI架構(gòu)

              關(guān)于JNDI要注意的重要一點是,它提供了應(yīng)用編程接口(application programming interface,API)和服務(wù)提供者接口(service provider interface,SPI)。這一點的真正含義是,要讓你的應(yīng)用與命名服務(wù)或目錄服務(wù)交互,必須有這個服務(wù)的JNDI服務(wù)提供者,這正是JNDI SPI發(fā)揮作用的地方。服務(wù)提供者基本上是一組類,這些類為各種具體的命名和目錄服務(wù)實現(xiàn)了JNDI接口?很象JDBC驅(qū)動為各種具體的數(shù)據(jù)庫系統(tǒng)實現(xiàn)了JDBC接口一樣。作為一個應(yīng)用開發(fā)者,你不必操心JNDI SPI.你只需要確認(rèn)你要使用的每一個命名或目錄服務(wù)都有服務(wù)提供者。

              J2SE和JNDI

              Java 2 SDK 1.3及以上的版本包含了JNDI.對于JDK 1.1和1.2也有一個標(biāo)準(zhǔn)的擴展。Java 2 SDK 1.4.x的最新版本包括了幾個增強和下面的命名/目錄服務(wù)提供者:

              l LDAP(Lightweight Directory Access Protocol)服務(wù)提供者 l CORBA COS(Common Object Request Broker Architecture Common Object Services)命名服務(wù)提供者 l RMI(Java Remote Method Invocation)注冊服務(wù)提供者 l DNS(Domain Name System)服務(wù)提供者

              更多的服務(wù)提供者

              可以在如下網(wǎng)址找到可以下載的服務(wù)提供者列表:

              http://java.sun.com/products/jndi/serviceproviders.html 特別有意思的或許是如下網(wǎng)址提供的Windows 注冊表JNDI服務(wù)提供者:http://cogentlogic.com/cocoon/CogentLogicCorporation/JNDI.xml 這個服務(wù)提供者使你可以訪問Windows XP/2000/NT/Me/9x的windows注冊表。

                也可以在如下網(wǎng)址下載JNDI/LDAP Booster Pack:http://java.sun.com/products/jndi/ 這個Booster Pack包含了對流行的LDAP控制的支持和擴展。它代替了與LDAP 1.2.1服務(wù)提供者捆綁在一起的booster pack.關(guān)于控制和擴展的更多信息可以在如下網(wǎng)站看到: http://java.sun.com/products/jndi/tutorial/ldap/ext/index.html 另一個有趣的服務(wù)提供者是Sun的支持DSML v2.0(Directory Service Markup Language,目錄服務(wù)標(biāo)記語言)的服務(wù)提供者。DSML的目的是在目錄服務(wù)和XML之間架起一座橋梁。

              JNDI API

              JNDI API由5個包組成:

              l Javax.naming:包含了訪問命名服務(wù)的類和接口。例如,它定義了Context接口,這是命名服務(wù)執(zhí)行查詢的入口。 l Javax.naming.directory:對命名包的擴充,提供了訪問目錄服務(wù)的類和接口。例如,它為屬性增加了新的類,提供了表示目錄上下文的DirContext接口,定義了檢查和更新目錄對象的屬性的方法。 l Javax.naming.event:提供了對訪問命名和目錄服務(wù)時的時間通知的支持。例如,定義了NamingEvent類,這個類用來表示命名/目錄服務(wù)產(chǎn)生的事件,定義了偵聽NamingEvents的NamingListener接口。 l Javax.naming.ldap:這個包提供了對LDAP 版本3擴充的操作和控制的支持,通用包javax.naming.directory沒有包含這些操作和控制。 l Javax.naming.spi:這個包提供了一個方法,通過javax.naming和有關(guān)包動態(tài)增加對訪問命名和目錄服務(wù)的支持。這個包是為有興趣創(chuàng)建服務(wù)提供者的開發(fā)者提供的。

              JNDI 上下文

              正如在前面提到的,命名服務(wù)將名稱和對象聯(lián)系起來。這種聯(lián)系稱之為綁定(binding)。一組這樣的綁定稱之為上下文(context),上下文提供了解析(即返回對象的查找操作)。其他操作包括:名稱的綁定和取消綁定,列出綁定的名稱。注意到一個上下文對象的名稱可以綁定到有同樣的命名約定的另一個上下文對象。這稱之為子上下文。例如,如果UNIX中目錄/home是一個上下文,那么相對于這個目錄的子目錄就是子上下文?例如,/home/guests中g(shù)uests就是home的子上下文。在JNDI中,上下文用接口javax.naming.Context表示,這個接口是與命名服務(wù)交互的關(guān)鍵接口。在Context(或稍后討論的DirContext)接口中的每一個命名方法都有兩種重載形式:

              Lookup(String name):接受串名 l
              Lookup(javax.naming.Name):接受結(jié)構(gòu)名,
              例如,CompositeName(跨越了多個命名系統(tǒng)的名稱)或CompondName(單個命名系統(tǒng)中的名稱);它們都實現(xiàn)了Name接口。Compound name的一個例子是:cn=mydir,cn=Q Mahmoud,ou=People,composite name的一個例子是:cn=mydir,cn=Q Mahmoud,ou=People/myfiles/max.txt(這里,myfiles/max.txt是表示第二部分的文件名)

                  Javax.naming.InitialContext是實現(xiàn)了Context接口的類。用這個類作為命名服務(wù)的入口。為了創(chuàng)建InitialContext對象,構(gòu)造器以java.util.Hashtable或者是其子類(例如,Properties)的形式設(shè)置一組屬性。下面給出了一個例子:

              Hashtable env = new Hashtable(); // select a service provider factory env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContext"); // create the initial context Context contxt = new InitialContext(env);

              INITIAL_CONTEXT_FACTORY指定了JNDI服務(wù)提供者中工廠類(factory class)的名稱。Factory負(fù)責(zé)為其服務(wù)創(chuàng)建適當(dāng)?shù)腎nitialContext對象。在上面的代碼片斷中,為文件系統(tǒng)服務(wù)提供者指定了工廠類。表1給出了所支持的服務(wù)提供者的工廠類。要注意的是文件系統(tǒng)服務(wù)提供者的工廠類需要從Sun公司單獨下載,J2SE 1.4.x沒有包含這些類。

              表1:上下文INITIAL_CONTEXT_FACTORY的值       Name Service Provider Factory
                         File System                                                               com.sun.jndi.fscontext.RefFSContextFactory 
                         LDAP                                                                       com.sun.jndi.ldap.LdapCtxFactory 
                         RMI                                                                         com.sun.jndi.rmi.registry.RegistryContextFactory 
                         CORBA                                                                   com.sun.jndi.cosnaming.CNCtxFactory 
                         DNS                                                                         com.sun.jndi.dns.DnsContextFactory

              為了用名稱從命名服務(wù)或目錄中取得或解析對象,使用Context的lookup方法:Object obj=contxt.lookup(name)。Lookup方法返回一個對象,這個對象表示的是你想要找的上下文的兒子。


          ----------------------------------------------------------------------------------------------------------------------------

          對jndi總體的理解: jndi(java naming and directory Interface)它提供了一套使用命名和目錄服務(wù)的接口。用戶可以通過它來使用命名和目錄服務(wù)。就像jdbc一樣。jndi包括命名服務(wù)目錄服務(wù)兩部分,其中目錄服務(wù)包含目錄對象directory object,它包含若干屬性對象。提供了對屬性的很多操作。

          命名和目錄服務(wù): 命名和目錄服務(wù)我們一直在使用,如操作系統(tǒng)的文件系統(tǒng),它給我們提供對文件的操作,查詢,添加刪除等功能。DNS服務(wù)將url同ip地址綁定在了一起。命名和目錄系統(tǒng)的最主要的功能是將name和對象綁定。在它的基礎(chǔ)之上還提供更多的功能如lookup,search.而且存儲的對象是有一定層次結(jié)構(gòu)的。使用這樣的服務(wù)我們可以對對象更加有效的管理和操作。

          命名服務(wù)將一個名稱映射到一個對象。RMI Registry和CORBA Naming Service都是命名服務(wù)。
          目錄服務(wù)也存放對象,但目錄服務(wù)識別這些對象的相關(guān)屬性。可以用項目屬性來搜索目錄。

          在20世紀(jì)90年代早期,輕量級的目錄訪問協(xié)議(LightWeightDiretoryAccessProtocol,LDAP)被作為一種標(biāo)準(zhǔn)的目錄協(xié)議被開發(fā)出來,JNDI能夠訪問LDAP。





          j2se為jndi提供了5個擴展包:
          javax.naming;為訪問命名服務(wù)提供的api
          javax.naming.directory;為訪問目錄服務(wù)提供了基本的接口
          javax.naming.event;支持命名和目錄服務(wù)中的事件通知
          javax.naming.ldap; 支持ldap的包,
          javax.naming.spi;提供了不同命名和目錄服務(wù)可以掛接他們的實現(xiàn)的方法。


          context: context是一套name-to-object的綁定(bindings),可以理解為層次或目錄,它還可已包括下一層subContext。在使用命名和目錄服務(wù)時獲得initial context是對整個名字空間操作的入口。在目錄服務(wù)中是DirContext.

          -------------------------------

          JNDI(Java Naming and Directory Interface)是一個應(yīng)用程序設(shè)計的API,為開發(fā)人員提供了查找和訪問各種命名和目錄服務(wù)的通用、統(tǒng)一的接口,類似JDBC都是構(gòu)建在抽象層上。

          JNDI可訪問的現(xiàn)有的目錄及服務(wù)有:
          DNS、XNam 、Novell目錄服務(wù)、LDAP(Lightweight Directory Access Protocol 輕型目錄訪問協(xié)議)、 CORBA對象服務(wù)、文件系統(tǒng)、Windows XP/2000/NT/Me/9x的注冊表、RMI、DSML v1&v2、NIS。

          JNDI優(yōu)點:
          包含了大量的命名和目錄服務(wù),使用通用接口來訪問不同種類的服務(wù);可以同時連接到多個命名或目錄服務(wù)上;建立起邏輯關(guān)聯(lián),允許把名稱同Java對象或資源關(guān)聯(lián)起來,而不必指導(dǎo)對象或資源的物理ID。

          JNDI程序包:
          javax.naming:命名操作;
          javax.naming.directory:目錄操作;
          javax.naming.event:在命名目錄服務(wù)器中請求事件通知;
          javax.naming.ldap:提供LDAP支持;
          javax.naming.spi:允許動態(tài)插入不同實現(xiàn)。

          利用JNDI的命名與服務(wù)功能來滿足企業(yè)級APIs對命名與服務(wù)的訪問,諸如EJBs、JMS、JDBC 2.0以及IIOP上的RMI通過JNDI來使用CORBA的命名服務(wù)。

          JNDI與JDBC:
          JNDI提供了一種統(tǒng)一的方式,可以用在網(wǎng)絡(luò)上查找和訪問服務(wù)。通過指定一個資源名稱,該名稱對應(yīng)于數(shù)據(jù)庫或命名服務(wù)中的一個紀(jì)錄,同時返回數(shù)據(jù)庫連接建立所必須的信息。
          代碼示例:
          try{
          Context cntxt = new InitialContext();
          DataSource ds = (DataSource) cntxt.lookup("jdbc/dpt");
          }
          catch(NamingException ne){
          ...
          }

          JNDI與JMS:
          消息通信是軟件組件或應(yīng)用程序用來通信的一種方法。JMS就是一種允許應(yīng)用程序創(chuàng)建、發(fā)送、接收、和讀取消息的JAVA技術(shù)。
          代碼示例:
          try{
          Properties env = new Properties();
          InitialContext inictxt = new InitialContext(env);
          TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
          ...
          }
          catch(NamingException ne){
          ...
          }

          訪問特定目錄:舉個例子,人是個對象,他有好幾個屬性,諸如這個人的姓名、電話號碼、電子郵件地址、郵政編碼等屬性。通過getAttributes()方法
          Attribute attr = directory.getAttributes(personName).get("email");
          String email = (String)attr.get();
          通過使用JNDI讓客戶使用對象的名稱或?qū)傩詠聿檎覍ο螅?br>foxes = directory.search("o=Wiz,c=US", "sn=Fox", controls);

          通過使用JNDI來查找諸如打印機、數(shù)據(jù)庫這樣的對象,查找打印機的例子:
          Printer printer = (Printer)namespace.lookup(printerName);
          printer.print(document);

          瀏覽命名空間:
          NamingEnumeration list = namespace.list("o=Widget, c=US");
          while (list.hasMore()) {
          NameClassPair entry = (NameClassPair)list.next();
          display(entry.getName(), entry.getClassName());
          }

          參考資料:
          http://java.sun.com/products/jndi/examples.html
          http://java.sun.com/products/jndi/serviceproviders.html


          常用的JNDI操作:
          void bind(String sName,Object object);――綁定:把名稱同對象關(guān)聯(lián)的過程
          void rebind(String sName,Object object);――重新綁定:用來把對象同一個已經(jīng)存在的名稱重新綁定
          void unbind(String sName);――釋放:用來把對象從目錄中釋放出來
          void lookup(String sName,Object object);――查找:返回目錄總的一個對象
          void rename(String sOldName,String sNewName);――重命名:用來修改對象名稱綁定的名稱
          NamingEnumeration listBinding(String sName);――清單:返回綁定在特定上下文中對象的清單列表
          NamingEnumeration list(String sName);
          代碼示例:重新得到了名稱、類名和綁定對象。
          NamingEnumeration namEnumList = ctxt.listBinding("cntxtName");
          ...
          while ( namEnumList.hasMore() )  {
          Binding bnd = (Binding) namEnumList.next();
          String sObjName = bnd.getName();
          String sClassName = bnd.getClassName();
          SomeObject objLocal = (SomeObject) bnd.getObject();
          }



          --------------------------------------------------------------------------------------------------------------------------------------------------------
          了解名字服務(wù)和目錄服務(wù)的相關(guān)概念,有助于更好的使用JNDI

          Naming service

                 名字服務(wù)定義了如何將名字與對象關(guān)聯(lián),并通過名字如何找到對象的方法。典型的例子如:DNS將域名與IP關(guān)聯(lián),文件系統(tǒng)將文件名與文件相關(guān)聯(lián)。在名字服務(wù)中,主要的概念:

          -          名字(Names),在名字系統(tǒng)中實際對象的代號,如文件名,域名等,它會被用來查找關(guān)聯(lián)的對象。不同的系統(tǒng)中會有不同的命名規(guī)范,如文件系統(tǒng)采用“\”來表示層級,而DNS則使用“.”。

          -          綁定(Bindings),名字和實際對象的關(guān)聯(lián)。

          -          引用和地址(References and Addresses),當(dāng)對象不能直接被存儲在名字系統(tǒng)時,就必須使用引用,通過引用找到實際的對象。在系統(tǒng)中,保存的引用的內(nèi)容被稱為地址。引用還有另一個用處:在名字系統(tǒng)中,缺少象關(guān)系數(shù)據(jù)庫中外鍵的概念。通過使用引用,可以作為外鍵的一個取代辦法。

          -          上下文(Context),它是一個名字-對象集合,提供了與名字系統(tǒng)交互的主要操作,如查找、綁定、去綁定。子上下文(subcontext)與它的關(guān)系類似文件系統(tǒng)中目錄和子目錄的關(guān)系,子上下文被包含在一個上下文中,通過父上下文中的一個名字與子上下文關(guān)聯(lián)。

          -          名字系統(tǒng)和名字空間(Naming Systems and Namespaces),名字系統(tǒng)是相同類型的上下文的集合,它提供名字服務(wù);名字空間,是名字系統(tǒng)中的名字集合,如文件系統(tǒng)的文件名和目錄。

          Directory service

                 目錄服務(wù)是名字服務(wù)的擴展,它除了關(guān)聯(lián)名字和對象,還允許對象包含屬性。目錄系統(tǒng)通常以層次結(jié)構(gòu)組織數(shù)據(jù)。在目錄服務(wù)中的主要概念:

          -          屬性(Attributes),它屬于目錄對象,它是(名字,值)對,屬性可以有多個值。

          -          目錄和目錄服務(wù)(Directories and Directory Services),目錄是目錄對象的集合;目錄服務(wù)則提供與目錄相關(guān)的服務(wù),創(chuàng)建、刪除和修改存放在目錄中的對象的屬性。

          -          查找和查找過濾器(Searches and Search Filters),獲取目錄對象的操作就是查找;過濾器是類似查找條件的對象。

          基本使用

           

          ²        注冊JNDI提供者

          在使用JNDI之前,需要先獲取JNDI的提供者,并在系統(tǒng)注冊它。與JNDI相關(guān)的系統(tǒng)屬性在javax.naming.Context中定義,常用的屬性:

          -          java.naming.factory.initial,服務(wù)提供者用來創(chuàng)建InitialContext的類名。

          -          java.naming.provider.url,用來配置InitialContext的初始url

          -          java.naming.factory.object,用來創(chuàng)建name-to-object映射的類,用于NameClassPairReferences

          -          java.naming.factory.state,用來創(chuàng)建jndi state的類

          對于目錄服務(wù),由于一般需要安全設(shè)置,還通常使用:

          -          java.naming.security.authentication,安全類型,三個值:nonesimplestrong

          -          java.naming.security.principal,認(rèn)證信息。

          -          java.naming.security.credentials,證書信息。

          -          java.naming.security.protocol,安全協(xié)議名。

          使用System.setProperty注冊,如果程序不顯示說明,那么java會在classpath內(nèi)查找jdni.properties文件來完成注冊。jdni.properties例子:

          java.naming.factory.initial=com.codeline.db.MockInitialContextFactory

           

          ²        連接服務(wù)

          注冊之后,就可以實施服務(wù)連接了。對于名字服務(wù)由InitialContext開始,目錄服務(wù)則使用InitialDirContext。它們分別實現(xiàn)了ContextDirContext,這兩個接口分別對應(yīng)名字服務(wù)和目錄服務(wù)的接口,也是JNDI中最重要的兩個接口。

           

          -          連接名字服務(wù):

                              

          1System.setProperty(Context.INITIAL_CONTEXT_FACTORY," 
          2   com.sun.jndi.fscontext.FSContextFactory"); 
          3InitialContext ctx = new InitialContext(); 
          4
          5

           

          -          連接目錄服務(wù):

          1  Hashtable env = new Hashtable(); 
          2    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
          3    env.put(Context.PROVIDER_URL, "ldap://myserver.com/");
          4    env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
          5    //登錄ldap server需要的用戶名 
          6    env.put(Context.SECURITY_PRINCIPAL, "ldapuser"); 
          7    //登錄ldap server需要的密碼 
          8    env.put(Context.SECURITY_CREDENTIALS, "mypassword"); 
          9InitialDirContext ctx = new InitialDirContext(env); 


          -          多服務(wù)提供者:如果應(yīng)用包含多個服務(wù)提供者,在連接時略有不同。以名字服務(wù)為例:

           

          1Hashtable env = new Hashtable(); 
          2  env.put(Context.INITIAL_CONTEXT_FACTORY, 
          3"com.sun.jndi.rmi.registry.RegistryContextFactory"); 
          4  env.put(Context.PROVIDER_URL, "rmi://myserver.com:1099"); 
          5  //使用不同的構(gòu)造函數(shù) 
          6InitialContext ctx = new InitialContext(env); 

           

          ²        查找對象

          不論名字服務(wù)還是目錄服務(wù),都是使用lookup來查找對象的。除了可以使用String作為參數(shù)之外,lookup還可使用Name接口作為參數(shù)。

          1Greeter greeter = (Greeter)ctx.lookup("SayHello"); 

          如果想要獲得上下文中所有的對象名字,就使用lis返回NameClassPair列表。NameClassPair包含對象名字和對象類名。如果想要獲得實際的對象實例列表,就使用listBindings,它返回Binding列表。BindingNameClassPair的子類,它包含對象的實例。
          -          list

          1NamingEnumeration list = ctx.list("awt"); 
          2while (list.hasMore()) 
          3    NameClassPair nc = (NameClassPair)list.next(); 
          4    System.out.println(nc); 
          5}
           


          -          listBindings

          1NamingEnumeration bindings = ctx.listBindings("awt"); 
          2while (bindings.hasMore()) 
          3    Binding bd = (Binding)bindings.next(); 
          4    System.out.println(bd.getName() + "" + bd.getObject()); 
          5}
           

           

          ²        對象綁定

                -          使用bind添加綁定

          1Fruit fruit = new Fruit("orange");
          2ctx.bind("favorite", fruit); 

               -          使用rebind修改綁定

          1Fruit fruit = new Fruit("lemon");
          2ctx.rebind("favorite", fruit); 

          -          使用unbind去除綁定。

           

          1ctx.unbind("favorite"); 

           

          ²        對象改名

          使用rename可以給一個在上下文中的對象改名

          1ctx.rename("report.txt""old_report.txt"); 

          ²        獲取屬性

          屬性相關(guān)的接口是AttributeAttributes,它們都在javax.naming.directory包內(nèi)。通過DirContextgetAttributes方法就可以獲得對象的屬性集合,然后使用Attributesget方法獲得對應(yīng)的屬性,最后通過Attributeget方法就可以獲得屬性值。

          1String dn = "uid=me, dc=mycompany, dc=com, ou=customer, o=ExampleApp"
          2Context user = (Context)ctx.lookup(dn); 
          3//獲得所有屬性 
          4Attributes attrs = user.getAttributes(""); 
          5Attribute test= attrs .get("test"); 
          6Object testValue= test.get(); 

          上例中獲得的是user的所有屬性,在實際使用過程中,考慮網(wǎng)絡(luò)帶寬的影響,可以設(shè)置獲取要獲取的屬性列表:

          1String reqd_attrs = new String[] "surname""initials","title""rfc822mailalias"}
          2Attributes attrs = user.getAttributes("", reqd_attrs); 

           

          ²        查找和過濾

          使用search方法完成。

           

           1   public DirContext[] findUser(String initials,String surname,String country,String phone) 
           2        //構(gòu)造條件 
           3        BasicAttributes search_attrs = new BasicAttributes(); 
           4        search_attrs.put("initials", initials); 
           5        search_attrs.put("sn", surname); 
           6        search_attrs.put("c", country); 
           7        if(phone != null
           8          search_attrs.put("phonenumber", phone); 
           9        NamingEnumeration results = initial_ctx.search("ou=Customer,o=ExampleApp", search_attrs); 
          10        LinkedList found = new LinkedList(); 
          11        while(results.hasMore()) 
          12            SearchResults sr = (SearchResults)results.next(); 
          13            String name = sr.getName(); 
          14            Object ctx = sr.getObject(); 
          15            if((ctx == null|| !(ctx instanceof DirContext)) 
          16                found.add(initial_ctx.lookup(name)); 
          17            else 
          18               found.add(ctx); 
          19        }
           
          20        DirContext[] ret_val = new DirContext[found.size()]; 
          21        found.toArray(ret_val); 
          22        return ret_val; 
          23   }
           

           

          DirContext接口主要過濾方式:

           

           

           

          1.使用過濾字符串

           

          1String reqd_attrs = new String[] "cn""uid","rfc822mailalias" }
          2NamingEnumeration results = initial_ctx.search("ou=Customer, o=ExampleApp",search_attrs,reqd_attrs); 

           

          2.使用SearchControls,獲得更多的控制

           

          1SearchControls ctrls = new SearchControls(); 
          2ctrls.setCountLimit(20); 
          3ctrls.setTimeLimit(5000); 
          4ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE); 
          5NamingEnumeration results = initial_ctx.search("cat=books,ou=Products, 
          6o=ExampleApp","title=*Java*",ctrls); 

          ²        修改屬性

          使用DirContextInitialDirContextmodifyAttributes方法完成。所謂的修改過程,實際就是先構(gòu)造要修改的屬性列表,然后使用上述方法提交。對于屬性包含多個值時,需要把屬性的不修改的值也要包含,否則服務(wù)器會認(rèn)為那些值不再需要而刪除它們。

           1public void updateAddress(String dn,String address, String country, String phone) 
           2        BasicAttributes mod_attrs = new BasicAttributes(); 
           3        if(address != null
           4            mod_attrs.put("address", address); 
           5        if(country != null
           6            mod_attrs.put("c", country); 
           7        if(phone != null
           8            mod_attrs.put("phonenumber", phone); 
           9        if(mod_attrs.size() != 0
          10            initial_ctx.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, mod_attrs); 
          11}
           

          使用ModificationItem,也可一次進行多個不同的修改操作:

          ModificationItem[] mod_items = new ModificationItems[2];

          Attribute email = new BasicAttribute("rfc822mailalias", new_email);

          ModificationItem email_mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, email);

          Attribute addr = new BasicAttribute("address", address);

          ModificationItem addr_mod = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, addr);

          mod_items[0] = email_mod;

          mod_items[1] = addr_mod;

          initial_ctx.modifyAttributes(dn, mod_items);

          ²        創(chuàng)建上下文

          使用createSubcontext方法完成。

           

           1BasicAttributes attrs = new BasicAttributes(); 
           2attrs.put("initials", initials); 
           3attrs.put("sn", surname); 
           4attrs.put("rfc822mailalias", email); 
           5if(address != null
           6    attrs.put("address", address); 
           7if(country != null
           8    attrs.put("c", country); 
           9if(phone != null
          10    attrs.put("phonenumber", phone); 
          11initial_ctx.createSubcontext(dn, attrs); 

           

          ²        刪除上下文

          使用destroySubcontext方法完成。

          1initial_ctx.destroySubcontext(dn); 

           

          資料:
          jndi學(xué)習(xí)筆記  http://hankun.blogbus.com/logs/2005/12/1774694.html
           [精華] JNDI   http://www.chinaunix.net/jh/26/30421.html








          Author: orangelizq
          email: orangelizq@163.com

          歡迎大家訪問我的個人網(wǎng)站 萌萌的IT人
          posted on 2007-07-16 16:18 桔子汁 閱讀(4888) 評論(1)  編輯  收藏 所屬分類: J2EE

          評論:
          # re: JNDI 學(xué)習(xí) 2014-11-10 12:58 | didafor
          這篇文章的格式非常好,而且講解的也非常易懂:《JNDI介紹》http://www.strutshome.com/index.php/archives/659  回復(fù)  更多評論
            
          主站蜘蛛池模板: 定结县| 莱阳市| 泾源县| 和平区| 益阳市| 湘潭市| 罗甸县| 监利县| 攀枝花市| 金坛市| 和龙市| 辽宁省| 铁岭市| 建湖县| 方城县| 水城县| 珲春市| 秦安县| 盐源县| 盘锦市| 思茅市| 常州市| 内黄县| 高邑县| 阳信县| 图片| 潍坊市| 名山县| 华亭县| 昌邑市| 黄石市| 普宁市| 江孜县| 安岳县| 轮台县| 敦化市| 涞源县| 元谋县| 德江县| 郁南县| 黑河市|