`
hain
  • 浏览: 455564 次
  • 来自: ...
社区版块
存档分类
最新评论

开发基于JNDI的应用程序

    博客分类:
  • ejb
阅读更多

Java命名和目录接口(Java Naming and Directory Interface JNDI)是用于从Java应用程序中访问名称和目录服务的一组API。命名服务即将名称与对象相关联,以便能通过相应名称访问这些对象。而目录服务即其对象具有属性及名称的命名服务。

命名或目录服务允许您集中管理共享信息的存储,这在网络应用程序中很重要,因为它可以使这类应用程序更加一致和易于管理。例如,可以将打印机配置存储在目录服务中,这样所有与打印机相关的应用程序都能够使用它。

本文是一份代码密集型的快速入门指南,让您开始了解和使用JNDI。它:

  • 提供对JNDI的综述。
  • 描述JNDI的特性。
  • 提供使用JNDI开发应用程序过程中的体验。
  • 说明如何使用JNDI访问 LDAP 服务器,比如Sun ONE Directory Server
  • 说明如何使用 JNDI 访问J2EE 服务。
  • 提供示例代码,您可以对其进行修改,以用于您自己的应用程序。

JNDI综述

我们所有人每天都在不自知的情况下使用命名服务。例如,当您在浏览器中输入URL http://java.sun.com 时,域名系统(Domain Name System DNS)将这个以符号表示的URL转换为一个通信标识符(IP地址)。在命名系统中,对象的范围可以从位于DNS记录中的名称变动到应用程序服务器中的企业JavaBeans组件(Enterprise JavaBeans Components EJBs),还可以到轻量级目录访问协议(Lightweight Directory Access Protocol LDAP)中的用户配置文件。

目录服务是命名服务的自然扩展。二者的关键区别在于,目录服务允许属性(比如用户的电子邮件地址)与对象相关联,而命名服务则不然。这样,使用目录服务时,您可以基于对象的属性来搜索它们。JNDI允许您访问文件系统中的文件,定位远程RMI注册表中的对象,访问诸如LDAP这样的目录服务,并定位网络上的EJB

很多应用程序选择使用JNDI都可以收到良好的效果,比如LDAP客户端、应用程序启动器、类浏览器、网络管理实用工具,或者甚至是地址簿。

JNDI架构

JNDI架构提供了一个标准的、与命名系统无关的API,这个API构建在特定于命名系统的驱动程序之上。这一层帮助把应用程序和实际的数据源隔离开来,因此无论应用程序是访问LDAPRMIDNS还是其他的目录服务,这都没有关系。换句话说,JNDI与任何特定的目录服务实现无关,您可以使用任何目录,只要您拥有相应的服务提供程序接口(或驱动程序)即可,如图1所示。


1: JNDI架构

注意,关于JNDI有一点很重要,即它同时提供应用程序编程接口(Application Programming Interface API)和服务提供程序接口(Service Provider Interface SPI)。这样做的实际意义在于,对于您的与命名或目录服务交互的应用程序来说,必须存在用于该服务的一个JNDI服务提供程序,这便是JNDI SPI发挥作用的舞台。一个服务提供程序基本上就是一组类,这些类针对特定的命名和目录服务实现了各种JNDI接口——这与JDBC驱动程序针对特定的数据系统实现各种JDBC接口极为相似。作为一名应用程序开发人员,您不需要担心JNDI SPI.。您只需确保,您为每个想使用的命名或目录服务提供了一个服务提供程序。

J2SEJNDI

JNDI被包含在Java 2 SDK 1.3 及其更新版本中。它还可以用作JDK 1.11.2的一个标准扩展。 Java 2 SDK 1.4.x的最新版本进行了改进,将以下命名/目录服务提供程序包括进来:

  • 轻量级目录访问协议Lightweight Directory Access ProtocolLDAP) 服务提供程序。
  • 公共对象请求代理架构(Common Object Request Broker Architecture CORBA)公共对象服务(Common Object Services COS)命名服务提供程序。
  • Java远程方法调用( Remote Method Invocation RMI)注册表服务提供程序。
  • 域名系统 Domain Name System DNS) 服务提供程序。

有关服务提供程序的更多内容

这里可以下载一系列服务提供程序。Windows注册表JNDI 提供程序(来自cogentlogic.com)可能会引起您特别的兴趣,因为它允许您访问Windows XP/2000/NT/Me/9x上的注册表。

此外,还可以下载JNDI/LDAP Bootster Pack。这个增强补丁包含对流行的LDAP控件和扩展的支持。它代替了与LDAP 1.2.1服务提供程序捆绑在一起的增强补丁。参见 Controls and Extensions 以获得更多信息。

另一个要考察的有趣的服务提供程序是SunDirectory Services Markup Language (DSML) v2.0提供程序。 DSML的目标是将目录服务与XML连接起来

JNDI API

JNDI API 包括5个包:

  • javax.naming: 包含用于访问命名服务的类和接口。例如,它定义了Context接口,该接口是执行查找时命名服务的入口点。
  • javax.naming.directory:扩展命名包以提供用于访问目录服务的类和接口。例如,它增加了新的属性类,提供代表一个目录上下文的DirContext 接口,并且定义了用于检查和更新与目录对象相关的属性的方法。
  • javax.naming.event: 当访问命名和目录服务时,为事件通知提供支持。例如,它定义了一个NamingEvent类,用于表示由命名/目录服务生成的事件,以及一个监视NamingEvents 类的, NamingListener 接口。
  • javax.naming.ldap: 这个包为LDAP 版本 3 扩展操作和空间提供特定的支持,而普通的javax.naming.directory 包没有提供这些支持。
  • javax.naming.spi: 这个包提供方法以动态插入对通过javax.naming及其相关包访问命名和目录服务的支持。只有那些对创建服务提供程序有着浓厚兴趣的开发人员才应该对这个包感兴趣。

JNDI 上下文

承前所述,命名服务是将名称与对象相关联。这种关联被称为绑定。一组这样的绑定被称为上下文,它提供返回对象的分解或查找操作。其他操作还可能包括绑定与解除绑定名称,以及列出被绑定的名称。注意,可以将一个上下文对象中的名称绑定到具有同样命名惯例的另一个上下文对象上。这被称为子上下文。例如,如果UNIX目录/home 是一个上下文,那么名称与其相关的目录便是子上下文。例如,/home/guests.,这里的guests 便是 home个子上下文。

JNDI中,上下文是使用javax.naming.Context 接口来表示的,而这个接口也正是与命名服务进行交互的主要接口。Context (或稍后将要讨论的DirContext)接口中的每个命名方法都有两种重载的形式:

  • lookup(String name): 接受一个字符串名称。
  • lookup(javax.naming.Name): 接受一个结构化的名称,比如CompositeName (一个跨越多个命名系统的名称) CompondName (一个位于单个命名系统中的名称);二者均实现了Name 接口。下面是一个复合名称的例子: cn=mydir,cn=Q Mahmoud,ou=People,还有一个组合名称的例子: cn=mydir,cn=Q Mahmoud,ou=People/myfiles/max.txt (这里的myfiles/max.txt 是代表第二部分的一个文件名)

javax.naming.InitialContext 是一个实现了 Context接口的类。使用这个类作为您到命名服务的入口点。要创建一个InitialContext 对象,构造器需要采用一组属性,形式为java.util.Hashtable 或其子类之一,比如Properties.。下面是一个例子:

Hashtable env = new Hashtable();

// select a service provider factory

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContext");

// create the initial context

Context contxt = new InitialContext(env);

INITIAL_CONTEXT_FACTORY 指定JNDI服务提供程序中工厂类的名称。该工厂负责为其服务创建一个合适的InitialContext 对象。在上面的代码片断中,指定了用于文件系统服务提供程序的一个工厂类。表1列出了用于所支持的服务提供程序的工厂类。注意,用于文件系统服务提供程序的工厂类需要Sun Microsystems单独下载,它并没有与J2SE 1.4.x一起发行。

1: Context.INITIAL_CONTEXT_FACTORY的值

名称

服务提供程序工厂

文件系统

com.sun.jndi.fscontext.RefFSContextFactory

LDAP

com.sun.jndi.ldap.LdapCtxFactory

RMI

com.sun.jndi.rmi.registry.RegistryContextFactory

CORBA

com.sun.jndi.cosnaming.CNCtxFactory

DNS

com.sun.jndi.dns.DnsContextFactory

要通过来自命名或目录服务的名称检索或解析(查找)一个对象,使用Context: Object obj = contxt.lookup(name)lookup方法。lookup 方法返回一个对象,该对象代表您想要查找的上下文的子上下文。

一个命名的例子

现在,让我们看一看一个使用命名服务的例子。在这个例子中,我们编写了一个简单的程序,用于查找一个其名称被当作命令行参数传入的对象。在这里,我们将使用一个用于文件系统的服务提供程序,而且因此,我们提供作为参数的名称必须是一个文件名。示例代码1中给出了相应代码。

示例代码 1: Resolve.java

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import java.util.Hashtable;

public class Resolve {

   public static void main(String argv[]) {

      // The user should provide a file to lookup

      if (argv.length != 1) {

         System.err.println("Usage: java Resolve ");

         System.exit(-1);

      }

      String name = argv[0];

      // Here we use the file system service provider

      Hashtable env = new Hashtable();

      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");

      try {

         // Create the initial context

         Context ctx = new InitialContext(env);

         // Look up an object

         Object obj = ctx.lookup(name);

         // Print it out

         System.out.println(name + " is bound to: " + obj);

         // Close the context

         ctx.close();

      } catch (NamingException e) {

         System.err.println("Problem looking up " + name + ": " + e);

      }

   }

}

在这里,我假定您使用的是Java 2SDK 1.4.x,它附带有几个服务提供程序(上面已经列出)。这个应用程序要使用文件系统服务提供程序 ,而在默认情况下,文件系统服务提供程序并未安装。因此,您需要下载并安装它。另一方面,如果您运行这个程序,而服务提供程序却还没有被安装,您将得到一个NoInitialContextException,意指无法找到服务提供程序工厂类,因此不能初始化这个类。接着,您需要在您的classpath中包括fscontext.jar providerutil.jar——或者像我一样,您可以简单地将这两个文件拷贝至JAVA_HOME\jre\lib\ext,这里的 JAVA_HOME 是指您的Java 2SDK安装的根目录。

要测试这个应用程序:

1.         确保您已经下载并安装了文件系统服务提供程序(正如上一段所讲的那样),因为这个服务提供程序并没有与J2SE 1.4.x一起提供。

2.         拷贝代码并将其粘贴到文件中,并将文件命名为Resolve.java

3.         使用javac 编译 Resolve.java

4.         使用java 解释器运行应用程序。

下面是一次示范运行:

prompt> java Resolve \classes

\classes is bound to: com.sun.jndi.fscontext.FSContext@f62373

如果您提供的名称是一个文件名,您将看到如下结果:

prompt> java Resolve \classes\Resolve.java

\classes\Resolve.java is bound to: C:\classes\Resolve.java

列出文件目录的内容

现在,让我们看一看如何使用其他JNDI API列出一个文件目录的内容。我们假定,您想让用户能够使用file:///这样的URL 来指定命令行参数。在这种情况下,您要设置一个新的属性PROVIDER_URL如示例代码2所示。Context listBindings 方法返回一个 NamingEnumeration对象,可以通过使用一个while 循环来迭代这个对象,如示例代码 2所示。

示例代码 2 Resolve2.java

import javax.naming.Binding;

import javax.naming.NamingEnumeration;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import java.util.Hashtable;

public class Resolve2 {

   public static void main(String argv[]) {

      // The user should provide a file to lookup

      if (argv.length != 1) {

         System.err.println("Usage: java Resolve2 ");

         System.exit(-1);

      }

      // Here we use the file system service provider

      Hashtable env = new Hashtable();

      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.FSContextFactory");

      env.put(Context.

分享到:
评论

相关推荐

    2022年基于JNDI的应用程序开发Java教程.docx

    Java Naming and Directory Interface (JNDI) 是Java应用程序用来访问命名和目录服务的一组API。JNDI的主要目的是提供一种标准化的方式来查找、访问和管理分布式环境中的资源,这些资源可以是对象、配置信息或者服务...

    websphere上发布基于jndi的应用

    在IT行业中,WebSphere是一款由IBM开发的企业级应用服务器,广泛用于部署和管理Java应用程序,尤其是基于JNDI(Java Naming and Directory Interface)的应用。JNDI是Java平台的一个核心API,它为Java应用程序提供了...

    基于JNDI的应用程序开发

    JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务...

    J2EE应用程序开发指南

    ### J2EE应用程序开发指南知识点总结 #### 一、J2EE概述 - **定义**:J2EE(Java 2 Platform, Enterprise Edition)是一种基于Java的平台标准,专为开发企业级应用而设计。 - **历史背景**:1993年,James Gosling...

    Spring JMS消息处理-不基于JNDI

    Spring JMS为应用程序提供了与消息中间件交互的能力,允许我们构建可扩展且解耦的系统。JNDI通常用于查找JMS资源,如ConnectionFactory和Destination,但在某些环境中,我们可能需要避免使用JNDI,例如在本地开发或...

    Spring JMS 消息处理-基于JNDI

    在IT行业中,Spring框架是Java开发中的重要工具,它提供了丰富的功能来简化应用程序的构建,尤其是在企业级应用中。Spring JMS(Java消息服务)模块是Spring框架的一部分,用于处理消息队列通信,这是一种异步处理和...

    JSP 应用程序开发指南

    **JSP(JavaServer Pages)应用程序开发指南** JSP是一种基于Java技术的动态网页开发工具,它允许开发者在HTML或XML文档中嵌入Java代码,从而实现动态网页的创建。本指南将深入讲解JSP的核心概念,帮助你掌握JSP的...

    jdbc构建基于web的应用程序

    在Web应用程序中,JDBC常用于实现用户登录验证、数据存储和检索等功能,极大地提升了开发效率和代码的可移植性。 1. **JDBC基础知识** - **JDBC驱动**:JDBC驱动是Java程序与数据库之间的桥梁,主要有四种类型的...

    Tomcat中JNDI原理

    JNDI提供了一种查找和定位应用程序所用资源的标准化方式,这些资源包括数据库连接、消息队列、EJBs、对象引用等。JNDI的核心概念包括: - **命名**:使用名字来标识资源。 - **目录服务**:存储命名信息和资源的...

    网站开发JNDI与连接池.pptx

    【网站开发JNDI与连接池】是Java Web开发中重要的技术组件,它们对于提高应用程序的性能和资源管理效率有着显著的作用。 **JNDI(Java Naming and Directory Interface)** 是Java EE的一项核心技术,它提供了一组...

    Struts+Jndi+Ajax

    Struts是Apache软件基金会的一个开源项目,它是一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架。Struts提供了处理HTTP请求、业务逻辑控制和视图展示的结构,使得开发者能够更好地组织代码,...

    快速的开发Hibernate应用程序

    总之,通过Eclipse 3.0.1中的Hibernate Synchronizer插件,开发者能够快速、高效地构建基于Hibernate的应用程序,减少与数据库交互的繁琐工作,专注于业务逻辑的实现。而随着Eclipse和Hibernate的不断升级,这样的...

    基于Java的实例开发源码-EJB中JNDI的使用源码例子.zip

    总的来说,JNDI在Java和EJB开发中扮演着关键角色,它为应用程序提供了一种统一的方式来访问和管理各种资源和服务。通过深入学习和实践,开发者可以更好地利用Java EE提供的强大功能,构建更高效、可扩展的企业级应用...

    JNDI 详细解读

    在实际的应用程序中,开发人员通常只需要使用上述几个包中的类即可,具体的调用细节对用户来说是透明的。JNDI API 提供了一个统一的接口来访问不同的 JNDI 服务,这些服务的具体实现可以由不同的 ServiceProvider 来...

    JavaEE程序设计与应用开发7.6作业答案

    3. **MVC(Model-View-Controller)模式**:这是一种常见的Web应用程序设计模式,JavaEE中的Struts、Spring MVC等框架都是基于此模式。在作业中,学生可能需要实现模型、视图和控制器之间的交互。 4. **JNDI(Java ...

    基于NetBeans的Java EE客户端应用程序.

    基于NetBeans的Java EE客户端应用程序的开发涉及到多个关键知识点: 1. **NetBeans IDE**:NetBeans提供了友好的图形用户界面,用于编写、调试和部署Java应用程序。它的特性包括代码提示、自动完成、项目管理、版本...

    jndi配置

    在 Web 应用程序中,特别是 Java EE 应用程序,JNDI 常用于管理资源绑定,例如数据源(DataSource)。通过将数据源等资源绑定到 JNDI 上,可以在不修改代码的情况下更改资源的配置细节,从而实现灵活的应用部署和...

    基于J2EE_EJB和SQL Server2000开发JSP WEB应用.pdf

    在当今的IT行业,Java 2 Enterprise Edition(J2EE)以及其相关技术,特别是Enterprise JavaBeans(EJB),是开发企业级应用程序的重要技术。EJB是J2EE平台的核心组件之一,它允许开发者通过定义商务逻辑来创建可...

    基于J2EE的BS方案数据应用开发

    - 应用程序通过Context对象在目录结构中查找和操作资源,每个Context代表目录结构中的一个节点。 - 初始化Context通常是通过`InitialContext`类完成,然后可以使用这个Context遍历整个目录树以获取所需资源。 在...

Global site tag (gtag.js) - Google Analytics