JNDI: The Java Naming and Directory Interface
什么是JNDI?
The Java Naming and Directory Interface是訪問(wèn)不同名字和目錄服務(wù)的統(tǒng)一API接口。
不同的服務(wù)使用不同的名字格式。
Java程序需要以相同的格式訪問(wèn)數(shù)據(jù)庫(kù),文件,目錄,對(duì)象和網(wǎng)絡(luò)。
JNID有兩部分接口:應(yīng)用程序接口和提供服務(wù)的接口。在應(yīng)用程序中使用API來(lái)訪問(wèn)名字或目錄服務(wù),在一個(gè)新的服務(wù)中使用SPI來(lái)提供服務(wù)。
JNDI結(jié)構(gòu)
名字服務(wù)(Naming Services)
名字服務(wù)提供一種方法,映射標(biāo)識(shí)符到實(shí)體或?qū)ο蟆?/SPAN>
你需要知道的幾條基本條款:
綁定:綁定是將一個(gè)不可分割的名字("原子"名字)與一個(gè)對(duì)象聯(lián)系起來(lái)。像DNS,我們用名字www.yahoo.com與IP地址216.32.74.53聯(lián)系起來(lái),一個(gè)文件對(duì)象用文件名afile.txt聯(lián)系起來(lái)。
名字空間;名字空間包含一組名字,但名字空間內(nèi)每個(gè)名字是唯一的。一個(gè)文件目錄就是一個(gè)簡(jiǎn)單的名字空間,如目錄C:\temp,在這個(gè)目錄下,不能有兩個(gè)相同名字的文件,但是,不同目錄下的兩個(gè)文件可能有相同的名字。
復(fù)合名字:復(fù)合名字是用名字空間構(gòu)成的唯一名字,有一個(gè)或多個(gè)"原子"名字構(gòu)成,取決于所在的名字空間。文件路徑就是一個(gè)復(fù)合名字,比如我們用C:\temp\myfile.txt,我們可以看到,這個(gè)名字由根目錄名(C:\),臨時(shí)目錄名(temp)和一個(gè)文件名(myfile.txt)構(gòu)成,這3個(gè)名字復(fù)合起來(lái)表示一個(gè)唯一的名字。
組合名字:組合名字能跨越多個(gè)名字空間。一個(gè)URL就是一個(gè)組合名字,如果你看見http://www.npu.edu/index.htm,你使用http服務(wù)連接到服務(wù)器,然后使用另一個(gè)名字空間/index.htm來(lái)訪問(wèn)一個(gè)文件。
目錄服務(wù)
目錄服務(wù)提供一組分成等級(jí)的目錄對(duì)象,具有可搜索的能力。
在目錄服務(wù)中存儲(chǔ)的對(duì)象可以是任何能用一組屬性描述的對(duì)象,每個(gè)對(duì)象都可通過(guò)一組屬性來(lái)描述該對(duì)象的能力。例如,一個(gè)Person對(duì)象可能有height,hair color,age,sex等屬性。目錄服務(wù)還可提供根據(jù)要求來(lái)搜索的能力,如我們可以使用Person的age屬性,搜索20-25歲間的Person對(duì)象,目錄服務(wù)將返回符合條件的Persion對(duì)象。這通常被稱作基于內(nèi)容的搜索。
在客戶端使用JNDI:
u 創(chuàng)建一個(gè)java.util.Hashtable或者java.util.Properties的實(shí)例。
u 添加變量到Hashtable或Properties對(duì)象:
由naming server提供的JNDI class類名。
包含aming server位置的URL。
安全信任書。
u 通過(guò)Hashtable或Properites或jndi屬性文件創(chuàng)建一個(gè)InitialContext對(duì)象。
示例:
import java.util.*;
import javax.naming.*;
…
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx = new InitialContext(env);
環(huán)境變量 |
相應(yīng)的常量 |
說(shuō)明 |
java.naming.factory.initial |
Context.INITIAL_CONTEXT_FACTORY |
Context Factory
類名,由服務(wù)提供商給出。 |
java.naming.provider.url |
Context.PROVIDE_URL |
初始化地址。 |
java.naming.security.
principal |
Context.SECURITY_PRINCIPAL |
服務(wù)使用者信息。 |
java.naming.security.
credentials |
Context.SECURITY_CREDENTIAL |
口令。 |
更多的配置示例:
Hashtable env = new Hashtable();
env.put (Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
env.put(Context.SECURITY_PRINCIPAL, "system");
env.put(Context.SECURITY_CREDENTIALS, "password here");
Properties env = new Properties();
env.setProperties ("java.naming.factory.initial",
"weblogic.jndi.WLInitialContextFactory");
env.setProperties("java.naming.provider.url" , "t3://localhost:7001");
env.setProperties("java.naming.security.principal" , "tommy");
env.setProperties("java.naming.security.credentials" ,"password here");
創(chuàng)建InitialContext:
Class Name: javax.naming.InitialContext
Interfaces that it implements: javax.naming.Context
Constructors:
public InitialContext();
public InitialContext(Hashtable configuration);
public InitialContext(Properties configuration);
以上所有方法都可能拋出NamingException。
一個(gè)Binding示例:
public static InitialContext getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext context = new InitialContext(env);
return context;
}
//Obtain the initial context
InitialContext initialContext = getInitialContext();
//Create a Bank object.
Bank myBank = new Bank();
//Bind the object into the JNDI tree.
initialContext.rebind("theBank",myBank);
一個(gè)Lookup示例:
public static InitialContext getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext context = new InitialContext(env);
return context;
}
//Obtain the initial context
InitialContext initialContext = getInitialContext();
//Lookup an existing Bank object.
Bank myBank = (Bank) initialContext.lookup("theBank");
可能發(fā)生的NamingException:
AuthenticationException
CommunicationException
InvalidNameException
NameNotFoundException
NoInitialContextException
枚舉所有名字對(duì)象:
NamingEnumeration Declaration:
public interface NamingEnumeration extends Enumeration {
public boolean hashMore() throws NamingException;
public Object next() throws NamingException;
public void close() throws NamingException; //jndi 1.2
}
try {
…
NamingEnumeration enum = ctx.list("");
while (enum.hasMore()) {
NameClassPair ncp = (NameClassPair) enum.next();
System.out.println("JNDI name is:" + ncp.getName());
}
}
catch (NamingException e) {…}
最后的示例:
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
import java.io.*;
public class ListAll {
public static void main(java.lang.String[] args) {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
try {
InitialContext ctx = new InitialContext(env);
NamingEnumeration enum = ctx.listBindings("");
while(enum.hasMore()) {
Binding binding = (Binding) enum.next();
Object obj = (Object) binding.getObject();
System.out.println(obj);
}
} catch (NamingException e) {
System.out.println(e);
}
} // end main
} // end List