JNDI(Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。
JNDI可访问的现有的目录及服务有:
DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS。
JNDI优点:
包含了大量的命名和目录服务,使用通用接口来访问不同种类的服务;
可以同时连接到多个命名或目录服务上;
建立起逻辑关联,允许把名称同Java对象或资源关联起来,而不必指导对象或资源的物理ID。
JNDI(Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。
JNDI可访问的现有的目录及服务有:
DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS。
JNDI优点:
包含了大量的命名和目录服务,使用通用接口来访问不同种类的服务;
可以同时连接到多个命名或目录服务上;
建立起逻辑关联,允许把名称同Java对象或资源关联起来,而不必指导对象或资源的物理ID。
JNDI程序包:
javax.naming:命名操作;
javax.naming.directory:目录操作;
javax.naming.event:在命名目录服务器中请求事件通知;
javax.naming.ldap:提供LDAP支持;
javax.naming.spi:允许动态插入不同实现。
利用JNDI的命名与服务功能来满足企业级APIs对命名与服务的访问,诸如EJBs、JMS、JDBC 2.0以及IIOP上的RMI通过JNDI来使用CORBA的命名服务。
JNDI与JDBC:
JNDI提供了一种统一的方式,可以用在网络上查找和访问服务。通过指定一个资源名称,该名称对应于数据库或命名服务中的一个纪录,同时返回数据库连接建立所必须的信息。
代码示例:
try{
Context cntxt = new InitialContext();
DataSource ds = (DataSource) cntxt.lookup("jdbc/dpt");
}
catch(NamingException ne){
...
}
JNDI与JMS:
消息通信是软件组件或应用程序用来通信的一种方法。JMS就是一种允许应用程序创建、发送、接收、和读取消息的JAVA技术。
代码示例:
try{
Properties env = new Properties();
InitialContext inictxt = new InitialContext(env);
TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory");
...
}
catch(NamingException ne){
...
}
访问特定目录:举个例子,人是个对象,他有好几个属性,诸如这个人的姓名、电话号码、电子邮件地址、邮政编码等属性。通过getAttributes()方法
Attribute attr =
directory.getAttributes(personName).get("email");
String email = (String)attr.get();
通过使用JNDI让客户使用对象的名称或属性来查找对象:
foxes = directory.search("o=Wiz,c=US", "sn=Fox", controls);
通过使用JNDI来查找诸如打印机、数据库这样的对象,查找打印机的例子:
Printer printer = (Printer)namespace.lookup(printerName);
printer.print(document);
浏览命名空间:
NamingEnumeration list = namespace.list("o=Widget, c=US");
while (list.hasMore()) {
NameClassPair entry = (NameClassPair)list.next();
display(entry.getName(), entry.getClassName());
}
参考资料:
http://java.sun.com/products/jndi/examples.html
http://java.sun.com/products/jndi/serviceproviders.html
常用的JNDI操作:
常用的JNDI操作:
void bind(String sName,Object object);――绑定:把名称同对象关联的过程
void rebind(String sName,Object object);――重新绑定:用来把对象同一个已经存在的名称重新绑定
void unbind(String sName);――释放:用来把对象从目录中释放出来
void lookup(String sName,Object object);――查找:返回目录总的一个对象
void rename(String sOldName,String sNewName);――重命名:用来修改对象名称绑定的名称
NamingEnumeration listBinding(String sName);――清单:返回绑定在特定上下文中对象的清单列表
NamingEnumeration list(String sName);
代码示例:重新得到了名称、类名和绑定对象。
NamingEnumeration namEnumList = ctxt.listBinding("cntxtName");
...
while ( namEnumList.hasMore() ) {
Binding bnd = (Binding) namEnumList.next();
String sObjName = bnd.getName();
String sClassName = bnd.getClassName();
SomeObject objLocal = (SomeObject) bnd.getObject();
同样一段代码,在Weblogic中已经运行通过,但Tomcat中却死活报错:
javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory.
------------------------
代码部分
-------------------------------------------------
public void connect() throws SQLException {
try {
initContext = getInitialContext();
/* 建立数据源对象
*/
ds = (DataSource) initContext.lookup("bb");
connection = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}
}
/**
* @todo 连接至tomcat,此段代码有问题
* @return
* @throws java.lang.Exception
*/
private static Context getInitialContext() throws NamingException {
String url = "jnp://localhost:1099";
String user = "admin";
String password = "";
Properties properties = null;
try {
properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(Context.PROVIDER_URL, url);
if (user != null) {
properties.put(Context.SECURITY_PRINCIPAL, user);
properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);
}
此处出错/
return new InitialContext(properties);
}
catch(NamingException e) {
throw e;
}
}
/**
* @todo 连接至Weblogic,测试时没问题
* @return
* @throws java.lang.Exception
*/
/*
private static Context getInitialContext() throws NamingException {
String url = "t3://localhost:7001";
String user = "admin";
String password = "111";
Properties properties = null;
try {
properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, url);
if (user != null) {
properties.put(Context.SECURITY_PRINCIPAL, user);
properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);
}
return new InitialContext(properties);
}
catch(NamingException e) {
throw e;
}
}
*/
----------------------------------------------------------------
看到很多的介绍,都是JNDI配置放在应用服务器上,但通过应用程序访问时是没有Web容器的,如何才能定位?
问题点数:100、回复次数:6
Top
1 楼bingobird(宾果鸟)回复于 2006-03-29 17:59:46 得分 0 这里的INITIAL_CONTEXT_FACTORY跟url该填什么?
Top
2 楼xiangbo520(充栋汗牛)回复于 2006-03-30 09:38:51 得分 0 在TOMCAT中访问JNDI需要在web.xml中进行一下引用,不能仅仅在虚拟目录描述文件中声明。
Top
3 楼bingobird(宾果鸟)回复于 2006-03-30 10:44:04 得分 0 TO:xiangbo520(充栋汗牛)
web.xml中该如何引用?望指教!
Top
4 楼humanity(怪事:WebSphere 5.1进入dump javacore_xx.txt死循环)回复于 2006-04-01 18:03:33 得分 50JNDI 的配置如下:
在你的 源文件下面根目录或者 /META-INF/下面放置:
jndi.properties 文件。
内容就是你在
properties.put() 方法里面 put 进去的那些参数设置。
编译之后他就到了 WEB-INF/classes 或者 /META-INF/ 下面去了。
还有一种方法就是 在 资源管理中用一个 jndi 表示一个字符串,他代表你的 jndi.properties 文件在什么地方,这样的话你的 jndi.properties 文件就可以不用放到 应用程序所在的目录下面去了而是可以放到任何地方,或者你用 URL 表示然后放到一个 FTP 服务器上都行, 只要你的用 properties.load(url.openStream()); 读那个文件就行了。
Top
5 楼xiangbo520(充栋汗牛)回复于 2006-04-02 09:45:39 得分 40虚拟目录描述:
<Context path="/DBTest" docBase="DBTest"
debug="5" reloadable="true" crossContext="true">
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true"/>
</Context>
web.xml文件中加入
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
参考上面的进行修改
使用
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();
具体请参考http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html
这是TOMCAT的自带官方文档
Top
6 楼XP_engineer(中国心)回复于 2006-04-06 10:37:58 得分 10同意楼上的意见,再这里就是需要修改以下TOMCAT中访问JNDI需要在web.xml中进行一下引用,不能仅仅在虚拟目录描述文件中声明。
}