jndi step by step (1) jndi 介绍

你真的十分了解JNDI吗?真的知道命名服务和目录服务的区别吗?
真的知道为什么有的时候 new InitContext() 会出错?原因是什么?
JNDI是J2EE的重要组成部分,让我们来好好学习一下Sun的JNDI教程吧,
把这些疑惑一一解开。

这些资料都来自Sun的JNDI教程,我会每天坚持翻译一点,但是不会全部翻译的,例如如何操作LDAP部分。
有的地方原文档有些啰嗦,我就改成简单的表达方式了。如果有翻译错的地方,请指证出来,我会修改。

 


1、命名服务

      “命名”是计算机系统中最基本的一个部分。人们给予实物一个名字,然后通过这个名字找到实物。例如,当你发送
电子邮件的时候,你必须知道收件人的地址;当你在文件系统里查找一个文件的时候,你必须知道文件的名字。
       命名服务就是这样的一个东西,它可以让你根据名字来找到一个实物。

       命名服务主要的功能就是能有好的把名字和实物映射到一起,例如上面提过的邮件地址。例如,我们所熟悉的DNS系统,
它就会把 www.sun.com 映射成 ip地址192.9.48.5。再例如一个文件系统,一个 c:\bin\autoexec.bat ,就可以让程序访问这个
文件。这两个例子都说明命名系统其实是广泛存在和使用的---从 Internet 到一个单机的系统。

1.1 名字
      
       为了在一个命名系统里找到某一个对象,你必须提供这个对象的名字才可以。这个命名系统决定名字的格式因该是什么
样子的。而这种格式,就被称为命名方式。

       例如,Unix 文件系统的命名方式是相对跟目录的文件名,每一级目录都必须以“/”来分隔开来。例如:/usr/hello,就
表示一个在 /usr 目录里的、名字叫 hello 的文件。

       DNS系统的命名方式,是不同的部分用“.”来分隔开来。因此,这个DNS名字 “sales.Wiz.com”,就表示了一个DNS项,名
字是 “sales”,但是请记住它是相对“Wiz.com”来说的。同样,“Wiz”是相对“com”的一个名字。

       LDAP的命名习惯则是从右到左,由“,”分隔开来。因此这个LDAP名字“cn=Rosanna Lee, o=Sun, c=US”,就命名了一个
名字是“cn=Rosanna Lee”的项,当然,它是相对“o=Sun, c=US”来说的。同样,“o=Sun”是相对“c=US”的一个名字。而且LDAP还有
一个规则,就是每个名字,必须是“名字/数值”对应的,而且用“=”来分开。

1.2 绑定(Binding)

       把一个名字和一个实际的对象联系在一起,就称为绑定。例如,一个文件名字和一个文件绑定在一起,一个域名和一个
IP地址绑定在一起,一个LDAP名字和一个LDAP项绑定在一起。

1.3 引用和地址

       有些对象是不能直接保存在命名系统里的,也就是说,我们不能把某些对象复制到命名系统里。但是,命名系统可以保存
一个指向对象的引用--就好像一个指针。一个引用只是告诉命名系统如何去找到一个被引用的对象,一个引用里不会包含很多的
信息,因为你可以从对象那里得到详细的信息。

       例如,一个“飞机”可能保存这样一些信息:乘客信息,驾驶员信息,飞行计划等等。但是,一个对这个“飞机”的引用,
可能只包含航班号和到达时间。
       对于一个文件对象的引用来说,可能只包含文件的名字。
       对于一个打印机对象的引用来说,可能只包含打印机的位置和所使用的通信协议。
       尽管对于一个对象的引用中可以包含任意的信息,但是我们最好还是确定一些该如何才能找到一个对象--这就是所谓的
地址了。
      
1.4 内容上下文(Context)

       内容上下文其实就是一系列的“名字-对象”的绑定。每一个内容上下文都有对应的命名规则。一个内容上下文都会提供一个
lookup 方法去查找一个对象,或许还会提供一些其它的方法,绑定新的“名字-对象”,解除一个绑定,或者列出全部的“名字-对象”
绑定。如果一个内容上下文里的某个“名字”对应的对象还是一个内容上下文,那这个“名字”对应的内容上下文可以被称为“子内容
上下文”(SubContext)。
      
       例如,在Unix 系统里,“/usr”就是一个内容上下文,那么“/usr/bin”则就是子内容上下文。在域名上面,“com”是一个内容
上下文,那么对于“sun.com”来说,“sum”就是“com”的子内容上下文。

1.5 命名系统和命名空间

       一个命名系统就是一系列具有相同命名方式并且提供一些相同操作的系统。例如,DNS就是一个命名系统,LDAP也是一个命名
系统。
       一个命名系统提供了命名服务,和基于名字的一些操作。命名服务通过它的接口来访问。例如,DNS提供了映射域名和IP的
命名服务,一个文件系统提供了文件名字映射文件的服务。
       命名空间就是一系列的命名系统的集合。例如,unix 系统的命名空间是由全部的文件和目录所组成。


2、目录服务

       许多的命名服务被扩展成了目录服务。目录服务不仅用名字和对象作为联系,而且使用属性和对象进行联系。因此,你不仅
可以通过名字来找到一个对象,你还可以通过属性来找到一个对象。

       电话公司的目录服务就是一个很好的例子。电话公司的系统把一个用户的名字和电话号码、地址联系在一起。一个目录服务
系统就像电话公司的一样--电话号码,地址,其实都是一个对象的属性。
       一个目录对象可以是一个打印机,一个人,一个电脑,甚至是一个网络。一个目录对象会包含它所必需的属性。

2.1 属性

       一个目录对象可以具有属性,例如一个打印机可以具有 型号,颜色等属性。一个用户对象可以具有电话号码,邮件地址等
属性。
       属性包含一个属性名称和许多的属性值。
       目录服务包含了一系列的目录对象,目录服务提供了许多方法来,例如创建,删除,等等。

2.2 查询和过滤

       你可以通过给目录服务系统提供一个名字来查询一个目录对象。当然了,对于一些目录服务系统,例如LDAP,比较主张使用
查询语句来得到目录对象。使用查询语句查询对象的时候,你不仅可以指定一个目录的名字,还可以指定目录的属性,甚至是可以使用
一些查询表达式。这种使用表达式的方式,就是过滤查询了。这种方式有时候也被称为“反向查询”或者“基于内容的”查询。
       例如,你可以从目录系统里查询所有年龄大于40岁的用户;你也可以查询所有IP地址以“192.113.50”开头的机器。
      
2.3 结合命名和目录服务

       目录服务通常会以层次的方式组织目录对象。例如,LDAP把所有对象组织成一个树的形式,被称为 Directory Information Tree
(DIT)。例如,一个“组织”对象,可能会包含一个“组”对象,而一个“组”对象可能会包含一个“人”对象。
       当目录对象以这种方式组织在一起的时候,除了可以被当作属性的“容器”以外,它们也可以被看成是命名服务对象了。
       
       更简单点说,命名服务提供了一种层次的服务,而目录服务提供了一种属性的服务。我们一定要区分它们的概念。
       从实际应用来说,我们可能只使用命名服务,而可以不必使用目录服务。但是如果我们使用了目录服务,那么一般都是要同时
使用命名服务的。

3、具有目录服务功能的Java 应用

        目录服务是计算机网络的一个重要组成部分。通过使用目录,你可以简化应用和对应用的管理。随着java应用的越来越广泛,
掌握访问目录服务的能力就很必要了。

3.1 目录服务的传统使用方式

        一个具有目录服务功能的应用,要么使用了命名服务,要么使用了目录服务。具有目录服务功能的应用和applets,和其他应
用一样,可以用传统的方式访问目录服务,也就是说,可以保存或者查询目录对象。一个Java邮件客户端,可以把一个目录服务作为
邮件地址本,可以从中查询邮件地址;一个Java邮件传输的代理程序,可以从中得到路由的信息;一个日历程序,可以从中得到用户的
设置信息。

        各种应用程序可以通过目录服务得到公用的基础信息。这种共享方式,可以让应用跨系统部署,甚至是跨网络部署,并且让
这些部署的耦合更加清晰,而且便于管理。例如,打印机配置和邮件路由信息都可以保存在目录服务里,这样,这些配置就可以被所有
需要打印机和邮件路由的信息的应用所调用。

3.2 把对象保存在目录服务里

        我们不仅可以按照传统的方式使用目录服务,Java应用也可以把目录服务作为一个对象的仓库来使用。例如,一个应用可以
从目录服务里得到一个打印机对象,然后发送一些信息给打印机对象让它打印出来。


4、JNDI 架构图

 

 


5、先来看看 jndi 的两个例子吧!

命名服务的一个例子,这个例子使用文件系统作为例子。你可以不必完全理解例子的内容,因为
我们后面会仔细的讲。

java 代码
  1. import javax.naming.Context;   
  2. import javax.naming.InitialContext;   
  3. import javax.naming.NamingException;   
  4. import java.util.Hashtable;   
  5.   
  6. class Lookup {   
  7.     public static void main(String[] args) {   
  8.  // Check that user has supplied name of file to lookup   
  9.  if (args.length != 1) {   
  10.      System.err.println("usage: java Lookup <filename></filename>");   
  11.      System.exit(-1);   
  12.  }   
  13.   
  14.  String name = args[0];   
  15.   
  16.  // Identify service provider to use   
  17.  Hashtable env = new Hashtable(11);   
  18.  env.put(Context.INITIAL_CONTEXT_FACTORY,    
  19.      "com.sun.jndi.fscontext.RefFSContextFactory");   
  20.   
  21.  try {   
  22.   
  23.      // Create the initial context   
  24.      Context ctx = new InitialContext(env);   
  25.   
  26.      // Look up an object   
  27.      Object obj = ctx.lookup(name);   
  28.   
  29.      // Print it out   
  30.      System.out.println(name + " is bound to: " + obj);   
  31.         
  32.      // Close the context when we're done   
  33.      ctx.close();   
  34.  } catch (NamingException e) {   
  35.      System.err.println("Problem looking up " + name + ": " + e);   
  36.  }   
  37.     }   
  38. }   
  39.   

目录服务的一个例子,这个例子使用LDAP系统作为例子。你可以不必完全理解例子的内容,因为
我们后面会仔细的讲。

java 代码
  1. import javax.naming.Context;   
  2. import javax.naming.directory.InitialDirContext;   
  3. import javax.naming.directory.DirContext;   
  4. import javax.naming.directory.Attributes;   
  5. import javax.naming.NamingException;   
  6. import java.util.Hashtable;   
  7.   
  8. /**  
  9.  * Demonstrates how to retrieve an attribute of a named object.  
  10.  *  
  11.  * usage: java Getattr  
  12.  */  
  13. class Getattr {   
  14.     public static void main(String[] args) {   
  15.  // Identify service provider to use   
  16.  Hashtable env = new Hashtable(11);   
  17.  env.put(Context.INITIAL_CONTEXT_FACTORY,    
  18.      "com.sun.jndi.ldap.LdapCtxFactory");   
  19.  env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");   
  20.   
  21.  try {   
  22.   
  23.      // Create the initial directory context   
  24.      DirContext ctx = new InitialDirContext(env);   
  25.         
  26.      // Ask for all attributes of the object    
  27.      Attributes attrs = ctx.getAttributes("cn=Ted Geisel, ou=People");   
  28.   
  29.      // Find the surname ("sn") and print it   
  30.      System.out.println("sn: " + attrs.get("sn").get());   
  31.   
  32.      // Close the context when we're done   
  33.      ctx.close();   
  34.  } catch (NamingException e) {   
  35.      System.err.println("Problem getting attribute: " + e);   
  36.  }   
  37.     }   
  38. }   
  39.   
  40.     
  41.   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值