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

}

}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章