admin 管理员组

文章数量: 1184232


2024年3月18日发(作者:lazarus和delphi的差距)

维普资讯

Microcomputer Applications Vo1.23,No.2,2007 学习园地 微型电脑应用 2007年第23卷第2期 

文章缩号:1OO7—757X(2007)02--0061一O3 

基于JNDI开发目录使能应用程序 

宋丽华,王海涛 

摘 要:本文简要地介绍了名字和目录服务的基本概念,说明了Java名字和目录服务接口(JNDI)的功能特点、体系结构及 

主要类和接口。在此基础上重点阐述并讨论了利用JNDI开发目录使能Java应用程序的一般步骤及编程中应注意的一些技术问 

题。 

关键词:目录;名字;JNDI Java;应用程序开发 

中圈分类号:TP317 文献标识码:A 

1 引言 

名字服务是任何计算机系统的基本设施。它把对人友好 

的“名字“映射为计算机系统使用的地址、标识符或对象。“名 

字”起着标识、组织对象的作用。目录服务是名字服务的扩展, 

在名字之外又为对象增加了属性(Attributes)。目录系统作为 

节差异。3)支持应用程序在传统形式之外,直接利用目录存 

储、检索Java对象。4)支持跨越多个名字空间的合成名,使不 

同目录相互作用成为可能。 

2 JNDI体系结构 

JNDI作为Java名字和目录服务的标准API(Application 

Program Interface),仅是一个接口而非实现。也就是说,为了 

种特殊用途的数据库,记录了现实世界中大量对象的信息, 

供用户(人、计算机应用程序等)做各种频繁查询和相对少量 

的修改。目录服务已经成为网络计算的关键部件,使用它存储 

共享信息,可以极大地简化应用程序,使之更加连贯和易于管 

理。 

使用JNDI,需要一个现有的目录服务(如LDAP),并且这一服 

务的某些关键特性,如命名规则等,约束着上层应用程序的行 

为。 

目录服务与名字设季的结合能够为人类网络管理员提供 

JNDI体系结构[】]包括一个应用编程接口API和一个服 

务提供者接口SPI(Service Provider Interface)。API由javax. 

naming和javax.naming.directory两个包组成,供应用程序访 

问名字和目录服务;SPI是名字和目录服务透明接人的挂钩, 

仅包括javax.nainmg.spi。JNDIv1.2中的另外两个包javax. 

naimg.event和javax.naming.1dap分别提供了事件和LDAP 

种便于理解的名字空间。在分布式计算、网络管理等方面有 

着越来越广泛的应用。例如,企业的计算环境通常是由几种表 

示不同部分的合成名字空间的名学设施组成的,Internet域名 

系统可用作企业内不同机构的顶级名字设施;目录服务可作 

为配置信息的存储仓库支持设备的配置管理,简化网络管理 

人员的手工操作,实现自动配置NetWare和Windows2000操 

作系统都使用了目录服务集中组织、控制和管理对网络资源 

的访问。所谓目录使能(Directory--enabled)的应用程序,就是 

利用了名字服务或目录服务的应用程序[1]。现有目录服务种 

类繁多,存储格式、访问协议等各不相同,开发目录使能的应 

用程序存在一定的难度。 

JNDI(Java Naming and Directory Interface)作为提供名 

v3的辅助功能。JNDI体系结构如图1所示。 

字和目录功能的Java API,独立于具体的目录实现,使应用程 

序能够通过统一的方式访问多种名字和目录服务。基于JNDI 

的Java应用程序和小程序,既可以像其他网络应用一样,以传 

统方式存储、检索目录对象属性,也可以把目录作为一个对象 

仓库,存取和检索Java对象。JNDI具有如下优点:1)可与多种 

名字、目录服务(DNS、文件系统、x.500、LDAP等)无缝集成。 

2)统一的访问接口,屏蔽了不同目录服务之间协、接口等的细 

图1 JNDI体系结构 

利用JNDI实现目录使能的Java应用程序至少需要四部 

分软件一Java虚拟机、JNDI软件包、目录服务系统以及与其 

相应的服务提供者软件包。其中服务提供者是SPI对特定目 

录服务的实现,位于SPI下层,如上图中标有LDAP、CORBA 

①作者筒介:宋丽华,解放军理工大学通信工程学院,南京

王海涛,解放军理工大学通信工程学院,南京

210007 

210007 

・61・ 

维普资讯

Microcomputer Applications Vo1.23,No.2,2007 学习园地 微型电脑应用 2007年第23卷第2期 

字样的图块所示。它一般由目录提供商实现,作为JNDI与特 

定目录服务之间的联结纽带把JNDI API映射到具体的目录 

服务调用,与JNDI一起组成客户端,与目录服务器端交互。 

在JNDI视图下,目录不再局限于存储一般的条目,它完 

全支持用户直接存取Java对象[2。]。若下层服务提供者支持, 

存取一个Java对象可以有以下几种选择: 

1)对象可序列化,以其序列化后的字节流形式存储的目 

录中,读出时反序列化。 

2)不能或不适于直接存储(序列化)时,可间接存储对象 

的一个引用(Reference),引用中包含了重建对象信息。 

3)象实现了DirContext接口,目录中存储的是代表对象 

的一系列属性。这在与非Java应用程序的交互中非常有效。 

4)Java RMI远程对象或C0RBA对象。 

389/0=JNDI”); 

//所有的目录操作都有可能抛出异常,因此必须封装在 

try\catch语句内 

try{ 

//创建初始上下文对象 

DirContext ctx—new InitialDirContext(env): 

//查找子树下名为OU—Female,OU=People的对象 

DirContext ctx一(DirContext)initialCtx.1ookup(“OU— 

Female,OU=People”);//在ou=Femalecn下绑定一个名为cn 

Rose Smith的Person对象,首先要在环境变量中指定Per— 

//应的状态工厂和对象工厂 

ctx.AddToEnvironment(Context.STATE—FACTO— 

son对 

5)提供了状态工厂和对象工厂的对象。 

关于Java对象在LDAP中的表示问题,即LDAP的 

Schema扩展在RFC2713中定义。RFC2714定义了C0RBA对 

象引用在LDAP中的表示。 

JNDI中包含的主要类、接口及它们问的相互关系见图2。 

RIES,“Person.StaFactory”); 

ctx.AddToEnvironment(Context.OBJECT—FACT0一 

RIES,“Person.ObjFactory”) 

Person rose—new Person(“Rose,”“Smith”); 

ctx.bind(“on—Rose Smith”,rose); 

//为cn=Rose smith增加一个电话号码属性 

BasicAttributes attrs—new Basic:Attributes(); 

asiBcAttribute attr — new asiBcAttribute 

(“phoneNumber”,“025—4623443”); 

attrs.put(attr); 

ctx.modifyAttributes(“cn—Rose Smith”,DirContext. 

ADD—ATTRIBUTE,attrs); 

//查找cn=Rose Smith,得到一个Person对象 

[【==二歪 

一 

正 

 l竺 兰塑竺!

Person Person一(Person)ctx.1ookup(“cn—Rose 

Smith”); . 

//查找cn—Rose Smith对应的目录对象类的定义 

图2 JNDI主要类、接口关系图 

DirContext classDef=ctx.getSchemaClassDefinition(“cn 

Rose Smith”); 

3使用JNDI开发目录使能程序的一般步骤 

本节以LDAP目录服务为例,说明利用JNDI开发目录使 

能的Java应用程序的一般步聚。假设一台名为may的服务器 

上运行有LDAP目录服务,且在389端口监听请求信息。选用 

SUN公司免费提供的LDAP服务提供者: 

第一步,因为JNDI中所有的目录操作都相对于一个特定 

的上下文对象[1],必须首先获得一个初始上下文对象引用。为 

完成这一步,首先要在环境变量中指定所使用的目录服务和 

}catch(NamingException err){ 

//异常处理 

} 

以上的例子虽然针对LDAP,但由于JNDI独立具体的目 

录实现,因此具有一般性。对开发过程来讲,底层目录服务的 

不同只体现在服务提供者、URL等环境变量上,其余大部分 

关于上下文操作的代码均可通用,这就大大减少了编程量,降 

低了发的复杂性。 

服务提者以及其他一些必须的参数,如与安全相关的信息等。 

//创建环境变量,指定要使用的目录服务和服务提供者 

Hashtable env=new Hashtable(); 

env.put(Context.INITIAL—C0NTEXT—FACTORY 

4其它需要注意的问题 

在用JNDI编写目录使能的Java应用程序时,有一些细节 

问题需要注意: 

com.sun.jndi.1dap.LdapCtxFactory"); 

1)名字参数与名字空间。名字分两种:合成合(composite 

name)与复合名(compound name)。合成名可以跨越多个名字 

env.put(Context.PROVIDER—URL,“Idap://may: 

・62・ 

维普资讯

Microcomputer Applications Vo1.23,No.2,2007 技术交流 微型电脑应用 2007年第23卷第2期 

空间,而复合名只存在于一个名字空间内。不同的名字空间有 

不同的命名规则,例如LDAP的名字从右至左,以“, 分隔,而 

UNIX文件系统的名字从左往右,以“/ 分隔。提供String类 

型的名字参数时,因为被作为合成名,所以不仅要考虑各名字 

空间的名字语法,还要考虑JNDI合成名的语法与特殊符以及 

Java语言本身对字符串的限制。例如一个包含反斜杠的 

LDAP名字“an—a\b ,根据LDAP的要求,“\,,要被另一个 

提供者后还会继续传递到各种状态、对象工厂,因此必须确保 

所使用的服务提供者和工厂是值得信任的。JNDI提供了灵活 

的机制,使用户可以随意定制所使用的服务提供者和工厂,但 

正是这种灵活性带来了安全上的隐患,用户必须所用的服务 

提供者和工厂十分dx,b。 

5小结 

目录服务供简便有效地存储、访问、管理和使用各种用户 

和资源的信息,在分布式计算中占有其重要的地位,能有效地 

降低管理成本,提高管理效率。当前名录服务种类繁多,访问 

协议、接口各异,如X.500、LDAP、DNS、NDS等。JNDI为Java 

应用程序访问目录服务提供了统一的接口,可与多种目录服 

务无缝集成。它不仅支持一般的目录操作,还允许直接存取 

Java对象,且操作简单,是实现目录使能的Java应用程序的首 

选工具。 

“\,,转义,“an—a\b 变成了“an—a\\b ;在JNDI合成中,“\,, 

作为元字符也需被转义,成为“an—a\\\b ;但这还不是最后 

结果,因为“\,,在Java字符串中同样具有特殊的含义,所以最 

后在行碍乒凹 移应 是 cn=a’I I’’’洒 

2)环境变量。在JNDI中环境变量用来给出配置信息,它 

允许用户对JNDI的使用进行定制。指定环境变量的方式有: 

在初始上下文构造器中提供环境变量参数;利用应用程序资 

源文件jndi.properties,JNDI会自动读取类路径中的所有jn— 

di.properties;在系统环境变量中给出某些标准JNDI环境变 

量;在applet的参数中包含某些标准变量值。初始上下文的环 

境变量是按一定顺序搜索上述四个来源的结合结果。上下文 

的环境变量有继承性,改变一个上下文的环境变量不会影响 

其余上下文。 

参考文献: 

[1]Rosannal Lee.The JNDI Tutorial[EB/OL].Http://java. 

sun.com/products/jndi/tutorial/,2000(1) 

3)统一资源定位符和联邦。在JNDI中,名字都是相对于 

某一个上下文进行解析,唯一的例外是一资源定位符URL,它 

的含义接近于绝对名。它可以作为名字参数提供初始上下文 

对象,不受当前名字空间的限制;也可以作为引用中的地址信 

息进行联邦。所谓联邦就是把多个名字系统连接到一起处理 

合成名的过程[1]。联邦是JNDI中第一位的概念,通过联邦,用 

户能够在不关心处理细节的情况下自由地穿越多个名字空 

间。为使URL得到正确处理,必须对“java.naming.factory. 

ur1.pkgs 环境变量进行设置,使其包含所有将用到的URL上 

下文实现(URL context implementation)的全路径的前缀。 

[2]Todd Sundsted.JNDI Overview[J].JavaWorld,2000(1). 

[3]Thomas E.Dasvis.Use JNDI to share objects between dif- 

ferent virtual machines[J].JavaWorld,1999(7). 

[43 3COM,Directory Enabled Networks and 3Corn’S Frame— 

work for Policy[J].Powered Networking,1998(5). 

[5]David Goodman,Colin Robbins.Understanding LDAP 8L 

X.5oo[J].EEMA,1997(8). 

[6]Steve Kille.X.500 and LDAP /OL].httpt|| 

org/,1998(2). 

.ema. 

4)安全性。JNDI并未定义自己的安全模型,它只是使用 

底层的Java平台和目录服务提供的安全模型[1],但它确实定 

义了与安全性相关的环境变量,如认证机制、安全协议等。这 

些环境变量包含了敏感信息(如口令字),它们被传递给服务 

[7]Jeff Hodges.An LDAP Roadmap 8L FAQ[J/OL].http:// 

WWW.kingsmountain.com/LDAPRoadmap/,1999(2). 

(收稿日期:2006年3月8日) 

(上接第2007年第1期第45页) 

Filter一“文件格式1(*LOG)m*.1ogm文件格式2 

程序显示,“打开记录文件 过程,实现打开要记录的文件和端 

口后,在文本框(TextBox)控件显示接收到的NMEA格式报 

文,并在后台把这些信息录入记录文件:“关闭记录文件 时, 

关闭文件。 

Private Sub mnuOpenLog--Click() 

im replDace 

(*.txt)m*.txtm文件格式3(*.*)m*.*“Eed With 

Do 

OpenLog.FileName= 

OpenLog.ShowOpen 

If Err=cdlCancel Then Exit Sub 

Temp=OpenLog.FileName 

With OpenLog‘CommonDialog控件 

‘如果文件已经存在,询问用户是否希望覆盖此文件或在 

此文件基础上添加内容. 

Ret—Len(Dir¥(Temp)) 

If Err Then 

Flags—cdlOFNHideReadOnly Or cdlOFNExplorer 

CancelError=True 

‘从用户处获得记录文件名称。 

ialDogTitle=“打开记录名称” 

・63・ 

MsgBox Error¥, 8 


本文标签: 目录 服务 名字 对象 环境变量