[转载自:http://www.lslnet.com/linux/f/docs1/i15/big5174174.htm]
http://java.sun.com/products/jndi/downloads/index.html
JNDI學習筆記(一)
由於工作需要學習了一天的JNDI有一些收穫,寫下來與大家分享.高手可以幫忙糾正和指點,在此謝過!
一:
幾個概念,Context,entry/object,filter.Attribute
Context:上下文,我的理解是相當與文件系統的中的目錄(JNDI的Naming Service是可以用操作系統的文件系統的,哈哈).
entry/object:一個節點,相當與文件系統中的目錄或文件.
filter:查詢/過濾條件是一個字符串表達式如:(&(objectClass=top)(cn=*))查詢出objectClass屬性為top,cn屬性為所有情況的entry.
Attribute:entry/object的屬性可以理解成JAVA對象的屬性,不同的是這個屬性可以多次賦值.
JNDI學習筆記(一) (怕發丟了分著發) 二: Naming Service的簡單例子,JNDI的全稱是名字與目錄服務,LDAP服務器都可以做Naming Service和Directory Service.JNDI Toturial上為了方面用File System做為naming service.以下的一個例子是演示一個從File System Lookup. [code] package study.jndi; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class Lookup{ public static void main(String[] args){ Hashtable env = new Hashtable(); String name = "C:/aaa.txt"; try{ env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory"); //use the file system as service provider Context ctx = new InitialContext(env); Object obj = ctx.lookup(name); System.out.println("the name " + name + " is bound to object:" + obj); }catch(Exception ex){ ex.printStackTrace(); } } } [/code] 為了運行的程序你要到http://java.sun.com/products/jndi/downloads/index.html下載JNDI的相關包,然後把兩個jar:fscontext.jar和providerutil.jar加入到你的CLASSPATH中.這樣就可以運行了.你可以做進一步的操縱如bind,unbind等等. Context ctx = new InitialContext();是以文件系統為初始上下文,這樣一來你可以把String name = "C:/aaa.txt";換成你系統中的任意目錄和文件的路徑名. env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory");是指明Service provider是文件系統. |
JNDI學習筆記(一) 由於我的工作主要是對Directory Service進行操作,所以重點學習了,javax.naming.directory包中的類.以下的幾個例子演示從LDAP上查詢ENTRY並得到屬性和屬性值. 假設我的LDAP是這樣存放的: 根節點c=com 二級節點 ou=t 以及其它 三級節點 ou = xc 以及其它 四級節點 cn=bsj. LDAP服務器安裝在我自己的機器上。 下面的一個例子是找到一個entry(object/節點,一個意思).然後取出所有的屬性值。 [code] package study.jndi; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.NamingEnumeration; import javax.naming.directory.DirContext; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.InitialDirContext; public class GetAttr{ public static final String ENTRY_NAME = "cn=bsj,ou=xc,ou=t,c=com"; public static void main(String[] args){ Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL,"ldap://127.0.0.1:10389/"); //login the ldap server try{ DirContext ctx = new InitialDirContext(env); Attributes allAttr = ctx.getAttributes(ENTRY_NAME); //get *a* object's all attributes for(NamingEnumeration attrs = allAttr.getAll();attrs.hasMore();){ Attribute attr = (Attribute)attrs.next(); System.out.println("Attribute is : " + attr.getID()); for(NamingEnumeration values = attr.getAll();values.hasMore();){ System.out.println(" value is : " + values.next()); } } }catch(NamingException ex){ ex.printStackTrace(); } System.out.println("SUCCESS!"); } } [/code] 這個例子需要到同樣的地址下載ldap.jar然後加入到CLASSPATH中,就可以執行,當然要保證你有一個配置到的LDAP服務器,我的是公司專用的服務器並且是配置好的,所以你要去找一個LDAP服務器安裝好在運行這個例子。這個例子的原理就是用ctx根據節點的DN(專有名詞,可以看做是文件名)來查找這個entry的所有屬性,然後在從屬性中得到所有的值,注意一個屬性可以有多個值,如果你熟悉LDAP就會知道了。 下邊這個例子在以上的例子基礎上加了一個設置entry返回的屬性都有哪些。 [code] package study.jndi; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.NamingEnumeration; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; public class GetAttr2{ public static final String ENTRY_NAME = "cn=bsj,ou=xc,ou=t,c=com"; public static void main(String[] args){ Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL,"ldap://127.0.0.1:10389/"); //login the ldap server String[] attrNames = new String[]{"abc"}; //get a attribute's value try{ DirContext ctx = new InitialDirContext(env); Attributes attrs = ctx.getAttributes(ENTRY_NAME,attrNames); for(NamingEnumeration ae = attrs.getAll();ae.hasMore();){ Attribute attr = (Attribute)ae.next(); System.out.println("Attribute : " + attr.getID()); for(NamingEnumeration ve = attr.getAll();ve.hasMore();){ System.out.println(" Value : " + ve.next()); } } }catch(NamingException ex){ ex.printStackTrace(); } System.out.println("SUCCESS!"); } } [/code] |
JNDI學習筆記(一) 下面的例子是利用DirContext提供的search方法對entry進行查找。 這個是查找一個CONTEXT下符合條件的一個或多個節點。 [code] package study.jndi; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.NamingEnumeration; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchResult; public class BasicSearch{ public static final String ROOT_ENTRY = "ou=xc,ou=t,c=com"; public static void main(String[] args){ Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL,"ldap://127.0.0.1:10389/"); try{ DirContext ctx = new InitialDirContext(env); Attributes matchAttrs = new BasicAttributes(true);//the attributes is interface matchAttrs.put(new BasicAttribute("cn","txc")); matchAttrs.put(new BasicAttribute("objectClass","top")); NamingEnumeration se = ctx.search(ROOT_ENTRY,matchAttrs); while(se.hasMore()){ SearchResult searchResult = (SearchResult)se.next(); System.out.println("**SearchResult : " + searchResult.getName()); JNDITools.listAttributes(searchResult.getAttributes()); } }catch(NamingException ex){ ex.printStackTrace(); } System.out.println("SUCCESS!"); } }[/code] |
JNDI學習筆記(一) 下面這個例子是應該是最常用的查詢操作的例子用到了DirContext的幾個search方法中的一個。 [code] package study.jndi; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.NamingEnumeration; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchResult; import javax.naming.directory.SearchControls; public class FilterSearch{ public static final String ROOT_ENTRY = "ou=xc,ou=t,c=com"; public static void main(String[] args){ Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL,"ldap://127.0.0.1:10389/"); try{ DirContext ctx = new InitialDirContext(env); SearchControls controls = new SearchControls(); String filter = "(&(objectClass=top)(cn=*))"; /** * OBJECT_SCOPE *controls.setSearchScope(SearchControls.OBJECT_SCOPE); *NamingEnumeration se = ctx.search("cn=txc,ou=xc,ou=t,c=com",filter,controls); */ controls.setCountLimit(100); //If the program attempts to get more than the count limit number of results, then a SizeLimitExceededException will be thrown controls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration se = ctx.search("c=com",filter,controls); while(se.hasMore()){ SearchResult result = (SearchResult)se.next(); System.out.println("**SearchResult : " + result.getName()); JNDITools.listAttributes(result.getAttributes()); } }catch(NamingException ex){ ex.printStackTrace(); } System.out.println("SUCCESS!"); } } [/code] 下面對以上的代碼進行解釋:search()方法的第一個參數是一個上下文執行時在這個上下文下進行查找,第二個參數是一個Filter字串意思是符合objectClass=top並且cn屬性為任意值的entry,第三個屬性是一個SearchControls對像在這個對象中設置一些參數用於控制查找,如controls.setSearchScope(SearchControls.SUBTREE_SCOPE);這個方法中有三個值,SUBTREE_SCOPE為查找給定上下文(第一個參數)下以及所有下級上下文下的所有entry,而ONELEVEL_SCOPE只查找給定上下文下的entry,OBJECT_SCOPE只查找一個entry。controls.setCountLimit(100); 是設置查找返回的最大結果,如果查詢的結果超過了這個值那麼就會拋出一個異常。還有一個設置超時時間的方法setTimeout()。 對了還有一個工具類用於打印給定屬性集合中的所有屬性以及屬性的值代碼如下: [code] package study.jndi; import javax.naming.NamingException; import javax.naming.NamingEnumeration; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; public class JNDITools{ public static void listAttributes(Attributes attrs)throws NamingException{ for(NamingEnumeration ae = attrs.getAll();ae.hasMore();){ Attribute attr = (Attribute)ae.next(); System.out.println("Attribute : " + attr.getID()); for(NamingEnumeration ve = attr.getAll();ve.hasMore();){ System.out.println(" value : " + ve.next()); } } } }[/code] 在這裡拋磚引玉,希望熟悉JNDI的朋友會給出好的建議,哈哈,更希望給和我一樣的初學者提供幫助。先寫到這裡。 參考資料:JNDI Toturial http://java.sun.com/products/jndi/tutorial/ |