JNDI介绍

目录
一、Naming 和 Directory 的概念
二、JNDI架构
三、JNDI packages
四、JNDI使用范例
五、结论
六、参考资料
七、范例程式完整内容

一、Naming和Directory 的概念

在介绍JNDI之前,我们先让读者对 naming与directory 有最基本的认识,进而了解使用JNDI 的原因。

Naming 在电脑系统上是最基本的服务之一,藉著名称 (names)与物件 (objects)的系结 (binding),使用者透过正确地描述环境(context)来存取欲使用的物件。例如:DNS(Domain Name System)将主机名称「javacenter.cis.th u.edu.tw」对应到 IP Address「140.128.104.30」,以方便使用者记忆。

Directory可视为 naming概念的扩充,让物件拥有属性 (attributes)以记录额外的资讯。於是,我们可以透过名称来查看(look up)物件并获得该物件的属性资讯,或是利用属性作为搜寻的过滤条件 (search filter)。例如:电话簿,记录著每个人登记的电话号码。从这个最常见的例子中不难看出directory与 database明显的差异之一:directory 的属性可以有很多笔资料,正如每个人可以同时拥有很多个电话号码。 Directory目前在电脑系统上较著名的应用系统与架构有 Novell公司的 NDS(Novell Directory Services)、Sun公司的NIS(Network Information Service),与即将成为网络上一个新标准的 LDAP(Lightweight Directory Access Protocol)[2]

Java在JNDI传统的应用就如同其他的程式语言一般,透过 Java applications 或applets,存取或检索(retrieve)在 directory内的物件属性。例如以Java 开发的电子邮件客户端程式(client program)能够透过 directory的方式来管理其中的通讯录;然而藉著扩充 directory的资讯,例如将印表机的组态存入directory, Java程式可以检索网路上符合求的印表机,然後把资料传送至该印表机列印。换言之,支援 directory的Java程式将能把directory 中的物件当成Java 的物件来使用。

二、JNDI架构

Java Naming and Directory Interface是一套提供naming和 directory功能的 API,Java应用程式开发者透过使用 JNDI,在naming和 directory方面的应用上就有了共通的准则。

JNDI包含一组API和一组SPI(Service Provider Interface)。Java 程式透过JNDI API 存取各种naming和 directory服务; JNDI SPI则使得各种naming和 directory服务透明化,允许Java程式透过JNDI API来存取这些服务。见下图 *。

图一、 Jndi架构图 [1]
三、JNDI packages

JNDI分为三个 packages:

javax.naming包含 naming服务的类别 (classes)和存取介面(interfaces for accessing)。其中 Contextapi让使用者可以定义物件在 namespaces中的「相对位置」。 naming服务便以 context为介面,提供查看、系结、物件更名(renaming objects)等功能。 InitialContextapi 提供naming或 directory服务的一个起始位置。因为在JNDI的世界中没有绝对的root观念,所有的动作都建立在context上;有了起始位置,使用者才能藉著它对其 context上的物件进行存取。

NamingExceptionapi则为JNDI定义的一组类别,负责侦测 (catch)所有发生在 naming或directory 服务里的例外状况 (exceptions)。

javax.naming.dire ctory 这个 package由 javax.naming扩充而来,提供存取 directory服务的功能─建立在naming 服务上,增加对 directory中的物件检索其属性(retrieve attributes)和透过指定属性为条件来搜寻(search)等功能。 DirContextapi提供物件在directory内 context的介面,与 Contextapi的运作方式类似,但更进一步定义了查询和更新directory中物件属性的方法(methods)。

javax.naming.spi 让系统发展者为特定的naming或 directory系统来撰写使用JNDI的应用程式,例如在 Plug-ins、Java Object Support及 Multiple Naming Systems(Federation)等方面的应用。

四、JNDI使用范例

使用JNDI要以下的软体及系统:

jdk 1.1.2 以上版本
JNDI API
Service Provider
Naming and Directory Server

首先设定classpath,编译时要的 classpath为 jndi.jar所在的完整路径。例如:



CLASSPATH=C:/jndi/lib/jndi.jar

执行时要的 classpath: service provider 所在的完整路径。例如:



CLASSPATH=C:/Novell/lib/njcl.jar

程式必须依照所使用的服务来import packages,本范例程式的目的为搜寻目录中的物件并列出其属性,因此  import naming和 directory两个 packages,请参照程式注标(1)。而在JNDI的程式中最重要的就是设定initial context ,通常至少 提供 factory.initial与 provider.url两个环境资讯,依照所选用的service provider而有所不同。在此程式中采用NDS为目录服务系统,於是必 引入 Novell公司开发的 SPI,见程式注标(2)。每个SPI所 的相关资讯,都应可在该SPI的说明文件中找到。设定完成 SPI所 的环境资讯之後,便可呼叫 constructor来产生 initial context;请注意在此我们使用的是目录服务,所以呼叫的是 InitialDirContext api,见程式注标(3)。接著指定搜寻时的过滤条件,base 所指的是搜寻开始的层级,在此范例中设定为一个目录 NCLTREE里的 o(organization)=N CL,见注标(4);filter则是设定搜寻的条件,程式要求搜寻所有 cn(common name)以 admin或Barabbas为起始的物件(使用者),见注标(5);被宣告为 SearchControlsapi 的constraints负责进行搜寻相关设定,在此仅设定搜寻的范围。搜寻范围通常有三种类型,分别是仅搜寻本身这一层、搜寻至下一层,及搜寻本层所有的整棵子树。本例中设定为搜寻整棵子树,见注标(6)。随後程式利用 DirContextapi的 searchapi method 来判断是否找到符合搜寻条件之物件,再以 SearchResultapi的 getAttributesapi method来取得属性资料并输出。

JNDI API更完整的使用方法,将於未来的文章中逐一介绍,因此本范例程式的内容便不再详细解说,请有兴趣的读者自行参考 JNDI的相关资料。范例程式的完整内容与执行范例附於文末。

五、结论

在网№网路爆炸性成长,各式网路服务争相崭露头角的今日,目录服务已经深入其中的各个层面,尤其是在电子商务的应用上。使用Java的程式发展者若想要跟上这一波潮流,JNDI将是开启目录服务大门的金钥匙!

六、参考资料

[1] The JNDI Tutorial by Rosanna Lee, htt p://www.javasoft. com/products/jndi /tutorial/index.h tml
[2] Novell Class Libraries for Java(including Novell providers for JNDI), http://developer.novell.com/ndk/doc/njcl/index.htm

七、范例程式完整内容

 代码:

import  javax.naming. * ; // (1)
import  javax.naming.directory. * ; // (1)
import  java.util.Properties;
import  java.util.Enumeration;

class  Search{
 
public   static   void  main(String[] args) {
  
try  {
       
/*  Create an environment for the initial directory context.
          The properties specify the NDS provider, 
          And the NDS Server's Tree Name. 
*/
       Properties env 
=   new  Properties();
       env.put(
" java.naming.factory.initial " ,
                    
" com.novell.service.nds.naming.NdsInitialContextFactory " ); // (2)
  env.put( " java.naming.provider.url " " nds://NCLTREE/ " ); // (2)
        /*  Create the initial directory context.  */
       DirContext ctx 
=   new  InitialDirContext(env); // (3)
        /*  Set up and perform the search.   Find all people in NCL
          whose common name starts with admin or Barabbas. 
*/
       String base 
=   " o=NCL " ; // (4)
       String filter  =   " (|(cn=admin*)(cn=Barabbas*)) " ; // (5)
       SearchControls constraints  =   new  SearchControls(); // (6)
       constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); // (6)
       NamingEnumeration results  =  ctx.search(base,filter,constraints);
       
/*  Print the search results.  */
       
if  ( ! results.hasMore()) {
          System.out.println(
" Nothing found. " );
       } 
else  {
            
/*  For each entry found.  */
          
while  (results.hasMore()) {
    SearchResult sr 
=  (SearchResult) results.next();
            System.out.println(sr.getName());
            Attributes attrs 
=  sr.getAttributes();
            
if  (attrs  ==   null ) {
               System.out.println(
" No attributes " );
            } 
else  {
                  
/*  For each attribute of the entry.  */
            
for  (NamingEnumeration ae  =  attrs.getAll(); ae.hasMore();) {
              Attribute attr 
=  (Attribute) ae.next();                  String id  =  attr.getID();
             
/*  For each value of the attribute.  */
               
for  (Enumeration vals  =  attr.getAll(); vals.hasMoreElements();
                     System.out.println(
"      " + id  +   " "   +  vals.nextElement()));
                }
               }
              }
             }
    } 
catch  (NamingException e) {
      
/*  Handle any name/directory exceptions.  */
      System.err.println(
" Search failed:  "   +  e);     
    } 
catch  (Exception e) {
        
/*  Handle any other types of exceptions.  */
      System.err.println(
" Non-naming error:  "   +  e.getMessage());
    }
  }
}
执行:
C:javasetjndi112 > java Search
admin.NCLNetworks.NCL
    NRD:Registry Index: com.novell.service.nds.net.NetStream@1275824c
    ACL: [All Attributes Rights];admin.NCLNetworks.NCL;
2
    ACL: Login Script;admin.NCLNetworks.NCL;
6
    ACL: Message Server;[Public];
2
    ACL: Print Job Configuration;admin.NCLNetworks.NCL;
6
    SA: Case Ignore String Tung Hai University
    Message Server: Distinguished Name NCLSERVER.NCLNetworks.NCL
    Internet EMail Address: Case Ignore String barabbas@dorm.thu.edu.tw
    Internet EMail Address: Case Ignore String s852858@student.thu.edu.tw
    Internet EMail Address: Case Ignore String tjJiang@ncl.cis.thu.edu.tw
    Home Directory: 
0 ;NCLSERVER_SYS.NCLNetworks.NCL;homeBarabbas
    Generational Qualifier: Case Ignore String None
    Surname: Case Ignore String Jiang
    OU: Case Ignore String Computer 
&  Information Science
    Used By: 
0 ;[Root];
    Initials: Case Ignore String None
    CN: Case Ignore String admin
    CN: Case Ignore String tjJiang
    Postal Office Box: Case Ignore String Tung Hai University
    Revision: 
272
    Password Required: 
false
    Telephone Number: Telephone Number 
+ 886 - 4 - 3594359  ext. < 71000 >
    S: Case Ignore String Taiwan
    NRD:Registry Data: com.novell.service.nds.net.NetStream@12a9824c
    Facsimile Telephone Number: None;
0 ;
    Network Address: 
1 ; 4 ;
    Network Address: 
1 ; 4 ;
    Network Address: 
1 ; 4 ;
Non
- naming error: String index  out  of range:  - 50
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值