JNDI操作(轉)
JNDI定義了一個Serializable接口類來爲應用信息的表達提供一種統一的方式。Serializable接口類包含了諸如地址、類型信息等用於訪問具體對象的信息。爲了能將對象的引用綁定到目錄樹中,該對象的類必須實現Referenceable接口,其中包含了方法 getReference()。開發者可以在該對象上調用getReference()方法來獲得Reference以用於綁定。Serializable接口與Referenceable接口有頗多相似之處,不同在於Referenceable可引用的對象只包含一些用於創建實際對象的信息,而Serializable會包含更多的甚至不適合存儲在目錄結構中的信息。
(2)綁定保存對象程序
package jndi;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.*;
public class ldapDataBind {
public static void main(String[]args){
//創建Hashtable以存儲JNDI將用於連接目錄服務的環境變量
Hashtable hs = new Hashtable();
//設置連接LDAP的實現工廠
hs.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
// 指定LDAP服務器的主機名和端口號
hs.put(Context.PROVIDER_URL, "ldap://localhost:389 ");
//給環境提供認證方法,有SIMPLE、SSL/TLS和SASL
hs.put(Context.SECURITY_AUTHENTICATION, "simple");
//指定進入的目錄識別名DN
hs.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
//進入的目錄密碼
hs.put(Context.SECURITY_CREDENTIALS, "password");
try {
// 得到初始目錄環境的一個引用
DirContext ctx = new InitialDirContext(hs);
// 新建一個對象
persons perObj = new persons("jordan","40");
//綁定對象
ctx.rebind ("uid = Jordan,ou = Bull,o = NBA ",perObj);
System.out.println("bind object object success " );
/*實例化一個屬性集合*/
Attributes attrs = new BasicAttributes(true);
/*建立一個屬性,其屬性名爲"mail"*/
Attribute personMail = new BasicAttribute("mail");
//設置屬性"mail"的值爲"[email protected]"、"[email protected]"、
"[email protected]"
personMail.add("[email protected]");
personMail.add("[email protected]");
personMail.add("[email protected]");
attrs.put(personMail);
/*建立一個屬性,其屬性名爲"uid",值爲001*/
attrs.put("uid","001");
/*建立一個屬性,其屬性名爲"cn",值爲jordan1*/
attrs.put("cn","jordan1");
/*建立一個屬性,其屬性名爲"sn",值爲NBA */
attrs.put("sn","NBA");
/*建立一個屬性,其屬性名爲"ou",值爲bull */
attrs.put("ou","bull");
System.out.println("bind object object success " );
/* 在識別名爲DN的目錄中增加一個條目*/
ctx.createSubcontext("uid = Jordan, ou = Wizzard,o=NBA",attrs);
//關閉初始目錄環境
ctx.close();
} catch (NamingException ex) {
System.err.println("bind object fail: " + ex.toString());
}
}
}
2.使用JNDI查找數據
前面已經介紹了怎麼樣將對象數據綁定到服務器,現在開始介紹如何取得調用綁定在服務器上的對象數據。
5 例6-2 使用JNDI查找數據。
要調用對象數據,首先就必須用JNDI查找綁定的對象和數據,查找出來後,再調用該對象。程序如下所示。
package jndi;
import java.nutil.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;
public class findUseBindObj {
public static void main(String[]args){
//創建Hashtable以存儲JNDI將用於連接目錄服務的環境變量
Hashtable hs = new Hashtable();
//設置連接Ldap的實現工廠
hs.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
// 指定LDAP服務器IP地址爲本機及端口號爲389
hs.put(Context.PROVIDER_URL, "ldap://localhost:389");
try {
// 得到初始目錄環境的一個引用
DirContext ctx = new InitialDirContext(hs);
//利用lookup查找返回指定DN的條目對象
persons pers =(persons)ctx.lookup("uid=Jordan,ou=Bull,o=NBA");
// 利用遠程對象調用遠程方法,返回Age變量的值
String age = pers.getAge();
// 利用遠程對象調用遠程方法,返回Name變量的值
String name = pers.getName();
//輸出Name的值
System.out.println("name is :" + name );
/*根據結點的DN來查找它的所有屬性, 然後再從屬性中得到所有的值,注意一個屬性可
以有多個值*/
Attributes attrs=ctx.getAttributes("uid=Jordan,ou=Wizzard,o=NBA");
//循環獲取並輸出這個屬性的所有屬性值
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());
}
}
//成功打印提示信息
System.out.println("find object success " );
//調用該對象的函數
pers.toString();
//關閉初始目錄環境
ctx.close();
} catch (NamingException ex) {
System.err.println(ex.toString());
}
}
}
對於作爲引用綁定在目錄樹中的對象,JNDI SPI 指定針對引用創建實際的對象。因此,在程序中只需要認爲用lookup()方法返回的對象就是實際對象,而不用在調用什麼方法來將引用轉換爲實際對象了,因爲所有的工作都由JNDI內部完成了。
6.2.7 JNDI查詢修改LDAP目錄條目
前面已經介紹瞭如何在LDAP服務器裏存儲一個對象:主要是利用一個DN將對象綁定到LDAP服務器中,然後用lookup(DN)查找定位到綁定的對象,再對該對象進行操作。但是往往使用DN查找非常難,用戶很難記住DN,因此我們可以使用其他屬性(比如CN=Cherry)來檢索包含那個屬性的條目。下面來介紹JNDI中相關屬性檢索的具體使用。
1.修改條目
很多時候可能要對LDAP服務器上的條目進行修改,如修改用戶密碼,更新應用的配置等。但修改必須由一個已認證過的用戶來執行,而且通常只能修改自己的密碼而不能修改其他信息,管理助手能夠修改電話號碼和郵件地址,而修改用戶標識這種工作由數據庫管理員完成。
6 例6-3 用JNDI修改LDAP條目。
package jndi;
import java.nutil.Hashtable;
import javax.naming.Context;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
public class jndiPropertyModify {
public static void main(String[] args){
Hashtable hs = new Hashtable();
//設置連接LDAP的實現工廠爲com.sun.jndi.ldap.LdapCtxFactory
hs.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.
LdapCtxFactory");
//指定提供服務的服務器IP地址和端口號
hs.put(Context.PROVIDER_URL,"ldap://localhost:389");
//使用簡單認證來認證用戶
hs.put(Context.SECURITY_AUTHENTICATION,"simple");
hs.put(Context.SECURITY_PRINCIPAL,"uid=Jordan,ou=Bull,o=NBA");
hs.put(Context.SECURITY_CREDENTIALS,"good");
try {
/*指定了JNDI服務提供者中工廠類(factory class)的名稱。Factory負
責爲其服務創建適當的InitialContext對象。在上面的代碼片斷中,爲文件
系統服務提供者指定了工廠類*/
DirContext ctx = new InitialDirContext(hs);
System.out.println("成功創建初始化context對象!");
//新建生成一個修改條目類對象,用於存放條目屬性
ModificationItem[] mdi = new ModificationItem[2];
// 把屬性mail的值置爲[email protected]
Attribute att0 = new BasicAttribute("mail",
"[email protected]");
// 把屬性call的值置爲12745827
Attribute att1 = new BasicAttribute("call","12745827");
//修改指定屬性mail
mdi[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
att0);
//增加新屬性call到條目
mdi[1]=new ModificationItem(DirContext.ADD_ATTRIBUTE,att1);
// 修改指定DN條目的屬性
ctx.modifyAttributes("uid=Jordan,ou=Bull,o=NBA",mdi);
}catch(Exception ex ){
ex.printStackTrace();
System.exit(1);
}
}
}
上面程序的作用是修改前面例子中增加的DN爲uid = Jordan,ou = Bull,o = NBA條目的屬性。
在程序中用DirContext.REPLACE_ATTRIBUTE來修改條目的mail屬性,在這裏如果原來的mail屬性有多個值時,都會被刪掉,取而代之的是新賦的值。用DirContext. REPLACE_ATTRIBUTE時,如果原來的屬性(mail)不存在時,就增加一個屬性,有則修改。
用DirContext.ADD_ATTRIBUTE來將一個新屬性增加到條目。真正起到修改作用的是ctx.modifyAttributes("uid = Jordan,ou = Bull,o = NBA",mdi)這條語句。
2.刪除條目
有時,當開發者不需要某個條目時,就可以把它從LDAP服務器上刪除。這隻要通過調用參數爲指定DN條目的DirContext接口的destorySubContext()方法來完成。
7 例6-4 用JNDI刪除LDAP條目。
package jndi;
import java.nutil.Hashtable;
import javax.naming.Context;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
public class jndiPropertyModify {
public static void main(String[] args){
Hashtable hs = new Hashtable();
//設置連接LDAP的實現工廠爲com.sun.jndi.ldap.LdapCtxFactory
hs.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.
LdapCtxFactory");
//指定提供服務的服務器IP地址和端口號
hs.put(Context.PROVIDER_URL,"ldap://localhost:389");
//使用簡單認證來認證用戶
hs.put(Context.SECURITY_AUTHENTICATION,"simple");
// 指定DN
hs.put(Context.SECURITY_PRINCIPAL,"uid=Jordan,ou=Bull,o=NBA");
// 指定認證密碼
hs.put(Context.SECURITY_CREDENTIALS,"good");
try {
/*指定了JNDI服務提供者中工廠類(factory class)的名稱。Factory負
責爲其服務創建適當的InitialContext對象。在上面的代碼片斷中,爲文件
系統服務提供者指定了工廠類*/
DirContext ctx = new InitialDirContext(hs);
//刪除指定DN條目
ctx.destroySubcontext("uid=Jordan,ou=Bull,o=NBA");
}catch(Exception ex ){
ex.printStackTrace();
System.exit(1);
}
}
}
(2)綁定保存對象程序
package jndi;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.*;
public class ldapDataBind {
public static void main(String[]args){
//創建Hashtable以存儲JNDI將用於連接目錄服務的環境變量
Hashtable hs = new Hashtable();
//設置連接LDAP的實現工廠
hs.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
// 指定LDAP服務器的主機名和端口號
hs.put(Context.PROVIDER_URL, "ldap://localhost:389 ");
//給環境提供認證方法,有SIMPLE、SSL/TLS和SASL
hs.put(Context.SECURITY_AUTHENTICATION, "simple");
//指定進入的目錄識別名DN
hs.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
//進入的目錄密碼
hs.put(Context.SECURITY_CREDENTIALS, "password");
try {
// 得到初始目錄環境的一個引用
DirContext ctx = new InitialDirContext(hs);
// 新建一個對象
persons perObj = new persons("jordan","40");
//綁定對象
ctx.rebind ("uid = Jordan,ou = Bull,o = NBA ",perObj);
System.out.println("bind object object success " );
/*實例化一個屬性集合*/
Attributes attrs = new BasicAttributes(true);
/*建立一個屬性,其屬性名爲"mail"*/
Attribute personMail = new BasicAttribute("mail");
//設置屬性"mail"的值爲"[email protected]"、"[email protected]"、
"[email protected]"
personMail.add("[email protected]");
personMail.add("[email protected]");
personMail.add("[email protected]");
attrs.put(personMail);
/*建立一個屬性,其屬性名爲"uid",值爲001*/
attrs.put("uid","001");
/*建立一個屬性,其屬性名爲"cn",值爲jordan1*/
attrs.put("cn","jordan1");
/*建立一個屬性,其屬性名爲"sn",值爲NBA */
attrs.put("sn","NBA");
/*建立一個屬性,其屬性名爲"ou",值爲bull */
attrs.put("ou","bull");
System.out.println("bind object object success " );
/* 在識別名爲DN的目錄中增加一個條目*/
ctx.createSubcontext("uid = Jordan, ou = Wizzard,o=NBA",attrs);
//關閉初始目錄環境
ctx.close();
} catch (NamingException ex) {
System.err.println("bind object fail: " + ex.toString());
}
}
}
2.使用JNDI查找數據
前面已經介紹了怎麼樣將對象數據綁定到服務器,現在開始介紹如何取得調用綁定在服務器上的對象數據。
5 例6-2 使用JNDI查找數據。
要調用對象數據,首先就必須用JNDI查找綁定的對象和數據,查找出來後,再調用該對象。程序如下所示。
package jndi;
import java.nutil.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.directory.*;
public class findUseBindObj {
public static void main(String[]args){
//創建Hashtable以存儲JNDI將用於連接目錄服務的環境變量
Hashtable hs = new Hashtable();
//設置連接Ldap的實現工廠
hs.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
// 指定LDAP服務器IP地址爲本機及端口號爲389
hs.put(Context.PROVIDER_URL, "ldap://localhost:389");
try {
// 得到初始目錄環境的一個引用
DirContext ctx = new InitialDirContext(hs);
//利用lookup查找返回指定DN的條目對象
persons pers =(persons)ctx.lookup("uid=Jordan,ou=Bull,o=NBA");
// 利用遠程對象調用遠程方法,返回Age變量的值
String age = pers.getAge();
// 利用遠程對象調用遠程方法,返回Name變量的值
String name = pers.getName();
//輸出Name的值
System.out.println("name is :" + name );
/*根據結點的DN來查找它的所有屬性, 然後再從屬性中得到所有的值,注意一個屬性可
以有多個值*/
Attributes attrs=ctx.getAttributes("uid=Jordan,ou=Wizzard,o=NBA");
//循環獲取並輸出這個屬性的所有屬性值
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());
}
}
//成功打印提示信息
System.out.println("find object success " );
//調用該對象的函數
pers.toString();
//關閉初始目錄環境
ctx.close();
} catch (NamingException ex) {
System.err.println(ex.toString());
}
}
}
對於作爲引用綁定在目錄樹中的對象,JNDI SPI 指定針對引用創建實際的對象。因此,在程序中只需要認爲用lookup()方法返回的對象就是實際對象,而不用在調用什麼方法來將引用轉換爲實際對象了,因爲所有的工作都由JNDI內部完成了。
6.2.7 JNDI查詢修改LDAP目錄條目
前面已經介紹瞭如何在LDAP服務器裏存儲一個對象:主要是利用一個DN將對象綁定到LDAP服務器中,然後用lookup(DN)查找定位到綁定的對象,再對該對象進行操作。但是往往使用DN查找非常難,用戶很難記住DN,因此我們可以使用其他屬性(比如CN=Cherry)來檢索包含那個屬性的條目。下面來介紹JNDI中相關屬性檢索的具體使用。
1.修改條目
很多時候可能要對LDAP服務器上的條目進行修改,如修改用戶密碼,更新應用的配置等。但修改必須由一個已認證過的用戶來執行,而且通常只能修改自己的密碼而不能修改其他信息,管理助手能夠修改電話號碼和郵件地址,而修改用戶標識這種工作由數據庫管理員完成。
6 例6-3 用JNDI修改LDAP條目。
package jndi;
import java.nutil.Hashtable;
import javax.naming.Context;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
public class jndiPropertyModify {
public static void main(String[] args){
Hashtable hs = new Hashtable();
//設置連接LDAP的實現工廠爲com.sun.jndi.ldap.LdapCtxFactory
hs.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.
LdapCtxFactory");
//指定提供服務的服務器IP地址和端口號
hs.put(Context.PROVIDER_URL,"ldap://localhost:389");
//使用簡單認證來認證用戶
hs.put(Context.SECURITY_AUTHENTICATION,"simple");
hs.put(Context.SECURITY_PRINCIPAL,"uid=Jordan,ou=Bull,o=NBA");
hs.put(Context.SECURITY_CREDENTIALS,"good");
try {
/*指定了JNDI服務提供者中工廠類(factory class)的名稱。Factory負
責爲其服務創建適當的InitialContext對象。在上面的代碼片斷中,爲文件
系統服務提供者指定了工廠類*/
DirContext ctx = new InitialDirContext(hs);
System.out.println("成功創建初始化context對象!");
//新建生成一個修改條目類對象,用於存放條目屬性
ModificationItem[] mdi = new ModificationItem[2];
// 把屬性mail的值置爲[email protected]
Attribute att0 = new BasicAttribute("mail",
"[email protected]");
// 把屬性call的值置爲12745827
Attribute att1 = new BasicAttribute("call","12745827");
//修改指定屬性mail
mdi[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
att0);
//增加新屬性call到條目
mdi[1]=new ModificationItem(DirContext.ADD_ATTRIBUTE,att1);
// 修改指定DN條目的屬性
ctx.modifyAttributes("uid=Jordan,ou=Bull,o=NBA",mdi);
}catch(Exception ex ){
ex.printStackTrace();
System.exit(1);
}
}
}
上面程序的作用是修改前面例子中增加的DN爲uid = Jordan,ou = Bull,o = NBA條目的屬性。
在程序中用DirContext.REPLACE_ATTRIBUTE來修改條目的mail屬性,在這裏如果原來的mail屬性有多個值時,都會被刪掉,取而代之的是新賦的值。用DirContext. REPLACE_ATTRIBUTE時,如果原來的屬性(mail)不存在時,就增加一個屬性,有則修改。
用DirContext.ADD_ATTRIBUTE來將一個新屬性增加到條目。真正起到修改作用的是ctx.modifyAttributes("uid = Jordan,ou = Bull,o = NBA",mdi)這條語句。
2.刪除條目
有時,當開發者不需要某個條目時,就可以把它從LDAP服務器上刪除。這隻要通過調用參數爲指定DN條目的DirContext接口的destorySubContext()方法來完成。
7 例6-4 用JNDI刪除LDAP條目。
package jndi;
import java.nutil.Hashtable;
import javax.naming.Context;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
public class jndiPropertyModify {
public static void main(String[] args){
Hashtable hs = new Hashtable();
//設置連接LDAP的實現工廠爲com.sun.jndi.ldap.LdapCtxFactory
hs.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.
LdapCtxFactory");
//指定提供服務的服務器IP地址和端口號
hs.put(Context.PROVIDER_URL,"ldap://localhost:389");
//使用簡單認證來認證用戶
hs.put(Context.SECURITY_AUTHENTICATION,"simple");
// 指定DN
hs.put(Context.SECURITY_PRINCIPAL,"uid=Jordan,ou=Bull,o=NBA");
// 指定認證密碼
hs.put(Context.SECURITY_CREDENTIALS,"good");
try {
/*指定了JNDI服務提供者中工廠類(factory class)的名稱。Factory負
責爲其服務創建適當的InitialContext對象。在上面的代碼片斷中,爲文件
系統服務提供者指定了工廠類*/
DirContext ctx = new InitialDirContext(hs);
//刪除指定DN條目
ctx.destroySubcontext("uid=Jordan,ou=Bull,o=NBA");
}catch(Exception ex ){
ex.printStackTrace();
System.exit(1);
}
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.