posts - 97,  comments - 93,  trackbacks - 0
          今天瀏覽網(wǎng)頁,看見篇寫JNDI比較基礎(chǔ),也比較詳細的文章,又自己整理了一下,post到新手區(qū)了,。。。。:)

          JNDIjava訪問名字和目錄服務(wù)的接口,與JDBC一樣,它僅僅只定義了一套服務(wù)接口,實現(xiàn)由具體廠商提供。作為j2ee核心組件之一,它為應(yīng)用程序查找其他程序組件和資源提供了統(tǒng)一的接口,其中最常見的用途就是數(shù)據(jù)源的配置、EJB名字查找、JMS相關(guān)配置等。JNDI的架構(gòu)如下圖。在JDK1.3中,已經(jīng)包含了JNDI,它分成五個包。每個包提供的功能:

          -          javax.naming,包含訪問命名服務(wù)的類和接口定義。

          -          javax.naming.directory,包含訪問目錄服務(wù)的類和接口定義。

          -          javax.naming.ldap,為ldapv3提供的擴展操作提供支持。

          -          javax.naming.event,為訪問命名和目錄服務(wù)時的事件通知提供支持。

          -          javax.naming.spi,為服務(wù)提供商提供的接口,一般用戶不會涉及。

          基本概念

           

                 了解名字服務(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),當對象不能直接被存儲在名字系統(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,認證信息。

          -          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ù)器會認為那些值不再需要而刪除它們。

           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); 

           


           


          posted on 2007-05-14 23:33 wqwqwqwqwq 閱讀(820) 評論(0)  編輯  收藏 所屬分類: Simple Java
          <2007年5月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789




          常用鏈接

          留言簿(10)

          隨筆分類(95)

          隨筆檔案(97)

          文章檔案(10)

          相冊

          J2ME技術(shù)網(wǎng)站

          java技術(shù)相關(guān)

          mess

          搜索

          •  

          最新評論

          閱讀排行榜

          校園夢網(wǎng)網(wǎng)絡(luò)電話,中國最優(yōu)秀的網(wǎng)絡(luò)電話
          主站蜘蛛池模板: 锡林郭勒盟| 英吉沙县| 开阳县| 广灵县| 宝丰县| 攀枝花市| 英超| 霍州市| 江城| 买车| 新龙县| 新蔡县| 闽侯县| 伊川县| 禄劝| 邳州市| 鄂伦春自治旗| 嵊泗县| 安岳县| 诏安县| 泾阳县| 伊金霍洛旗| 抚州市| 永靖县| 西丰县| 大埔县| 湟中县| 新竹县| 常熟市| 五原县| 青阳县| 鄄城县| 蕉岭县| 景德镇市| 西平县| 东阳市| 邯郸市| 海晏县| 眉山市| 抚松县| 曲周县|