?? 0091.htm
字號:
<html>
<head>
<title>新時代軟件教程:操作系統(tǒng) 主頁制作 服務器 設計軟件 網絡技術 編程語言 文字編輯</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
<!--
body, table {font-size: 9pt; font-family: 宋體}
a {text-decoration:none}
a:hover {color: red;text-decoration:underline}
.1 {background-color: rgb(245,245,245)}
-->
</style>
</head>
<p align="center"><script src="../../1.js"></script></a>
<p align="center"><big><strong>JNDI</strong></big></p>
<div align="right">---(文/姜天戩)</div>
<TABLE width="90%">
<TBODY>
<TR>
<TD class=page><A name=one>一、Naming和Directory 的概念</A> <BR>
<P>在介紹JNDI之前,我們先讓讀者對 naming與directory 有最基本的認識,進而了解使用JNDI 的原因。 </P>
<P>Naming 在電腦系統(tǒng)上是最基本的服務之一,藉著名稱 (names)與物件 (objects)的系結
(binding),使用者透過正確地描述環(huán)境(context)來存取欲使用的物件。例如:DNS(Domain Name System)將主機名稱「
javacenter.cis.th u.edu.tw」對應到 IP Address「 140.128.104.30」,以方便使用者記憶。 </P>
<P>Directory可視為 naming概念的擴充,讓物件擁有屬性
(attributes)以記錄額外的資訊。於是,我們可以透過名稱來查看(look up)物件并獲得該物件的屬性資訊,或是利用屬性作為搜尋的過濾條件
(search filter)。例如:電話簿,記錄著每個人登記的電話號碼。從這個最常見的例子中不難看出directory與
database明顯的差異之一:directory 的屬性可以有很多筆資料,正如每個人可以同時擁有很多個電話號碼。
Directory目前在電腦系統(tǒng)上較著名的應用系統(tǒng)與架構有 Novell公司的 NDS(Novell Directory
Services)、Sun公司的NIS(Network Information Service),與即將成為網絡上一個新標準的
LDAP(Lightweight Directory Access Protocol)<A
href="#2">[2]</A> 。 </P>
<P>Java在JNDI傳統(tǒng)的應用就如同其他的程式語言一般,透過 Java applications
或applets,存取或檢索(retrieve)在 directory內的物件屬性。例如以Java 開發(fā)的電子郵件客戶端程式(client
program)能夠透過 directory的方式來管理其中的通訊錄;然而藉著擴充
directory的資訊,例如將印表機的組態(tài)存入directory,
Java程式可以檢索網路上符合 求的印表機,然後把資料傳送至該印表機列印。換言之,支援 directory的Java程式將能把directory
中的物件當成Java 的物件來使用。 </P><A name=two>二、JNDI架構</A> <BR>
<P>Java Naming and Directory Interface是一套提供naming和 directory功能的
API,Java應用程式開發(fā)者透過使用 JNDI,在naming和 directory方面的應用上就有了共通的準則。 </P>
<P>JNDI包含一組API和一組SPI(Service Provider Interface)。Java 程式透過JNDI API
存取各種naming和 directory服務; JNDI SPI則使得各種naming和
directory服務透明化,允許Java程式透過JNDI API來存取這些服務。見下圖 *。 </P>
<TABLE>
<TBODY>
<TR>
<TD><IMG src="images/jndi_f1.gif"> </TD></TR>
<TR>
<TD>
<CENTER>圖一、 Jndi架構圖<A
href="#1">[1]</A>
</CENTER></TD></TR></TBODY></TABLE><A name=three>三、JNDI packages</A> <BR>
<P>JNDI分為三個 packages: </P>
<P>javax.naming包含 naming服務的類別 (classes)和存取介面(interfaces for accessing)。其中
Contextapi讓使用者可以定義物件在 namespaces中的「相對位置」。 naming服務便以
context為介面,提供查看、系結、物件更名(renaming objects)等功能。 InitialContextapi 提供naming或
directory服務的一個起始位置。因為在JNDI的世界中沒有絕對的root觀念,所有的動作都建立在context上;有了起始位置,使用者才能藉著它對其
context上的物件進行存取。 </P>
<P>NamingExceptionap i則為JNDI定義的一組類別,負責偵測 (catch)所有發(fā)生在 naming或directory
服務里的例外狀況 (exceptions)。 </P>
<P>javax.naming.dire ctory 這個 package由 javax.naming擴充而來,提供存取
directory服務的功能─建立在naming 服務上,增加對 directory中的物件檢索其屬性( retrieve
attributes)和透過指定屬性為條件來搜尋(search)等功能。 DirContextapi提供物件在directory內
context的介面,與 Contextapi的運作方式類似,但更進一步定義了查詢和更新directory中物件屬性的方法( methods)。
</P>
<P>javax.naming.spi 讓系統(tǒng)發(fā)展者為特定的naming或 directory系統(tǒng)來撰寫使用JNDI的應用程式,例如在
Plug-ins、Java Object Support及 Multiple Naming Systems(Federatio n)等方面的應用。
</P><A name=four>四、JNDI使用范例 </A><BR>
<P>使用JNDI 要以下的軟體及系統(tǒng): </P>
<TABLE width=200>
<TBODY>
<TR>
<TD align=right>jdk 1.1.2 以上版本 </TD></TR>
<TR>
<TD align=right>JNDI API </TD></TR>
<TR>
<TD align=right>Service Provider </TD></TR>
<TR>
<TD align=right>Naming and Directory Server </TD></TR></TBODY></TABLE>
<P>首先設定classpath ,編譯時 要的 classpath為 jndi.jar所在的完整路徑。例如: </P>
<P align=center>
<TABLE width="70%">
<TBODY>
<TR>
<TD class=detail><PRE><CODE>
CLASSPATH=C:\jndi\lib\jndi.jar
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>執(zhí)行時 要的 classpath: service provider 所在的完整路徑。例如: </P>
<P align=center>
<TABLE width="70%">
<TBODY>
<TR>
<TD class=detail><PRE><CODE>
CLASSPATH=C:\Novell\lib\njcl.jar
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>程式必 依照所使用的服務來import packages,本范例程式的目的為搜尋目錄中的物件并列出其屬性,因此 import naming和
directory兩個 packages,請參照程式注標<A
href="#p1">(1)</A>。而在JNDI的程式中最重要的就是設定initial
context ,通常至少 提供 factory.initial與 provider.url兩個環(huán)境資訊,依照所選用的service
provider而有所不同。在此程式中采用NDS為目錄服務系統(tǒng),於是必 引入 Novell公司開發(fā)的 SPI,見程式注標<A
href="#p2">(2)</A>。每個SPI所 的相關資訊,都應可在該SPI的說明文件中找到。設定完成
SPI所 的環(huán)境資訊之後,便可呼叫 constructor來產生 initial context;請注意在此我們使用的是目錄服務,所以呼叫的是
InitialDirContext api,見程式注標<A
href="#p3">(3)</A>。接著指定搜尋時的過濾條件,base
所指的是搜尋開始的層級,在此范例中設定為一個目錄 NCLTREE里的 o(organization)=N CL,見注標<A
href="#p4">(4)</A>;filter則是設定搜尋的條件,程式要求搜尋所有
cn(common name)以 admin或Barabbas為起始的物件(使用者),見注標<A
href="#p5">(5)</A>;被宣告為
SearchControlsapi
的constraints負責進行搜尋相關設定,在此僅設定搜尋的范圍。搜尋范圍通常有三種類型,分別是僅搜尋本身這一層、搜尋至下一層,及搜尋本層所有的整棵子樹。本例中設定為搜尋整棵子樹,見注標<A
href="#p6">(6)</A>。隨後程式利用
DirContextapi的 searchapi method 來判斷是否找到符合搜尋條件之物件,再以 SearchResultapi的
getAttributesapi method來取得屬性資料并輸出。 </P>
<P>JNDI API更完整的使用方法,將於未來的文章中逐一介紹,因此本范例程式的內容便不再詳細解說,請有興趣的讀者自行參考
JNDI的相關資料。范例程式的完整內容與執(zhí)行范例附於文末。 </P><A name=five>五、結論</A> <BR>
<P>在網№網路爆炸性成長,各式網路服務爭相嶄露頭角的今日,目錄服務已經深入其中的各個層面,尤其是在電子商務的應用上。使用Java的程式發(fā)展者若想要跟上這一波潮流,JNDI將是開啟目錄服務大門的金鑰!
</P><A name=six>六、參考資料</A>
<DL>
<DT>
<DD><A name=1>[1]</A> The JNDI Tutorial by Rosanna Lee, <A
href="../../www.javasoft.com/products/jndi/tutorial/index.html">htt
p://www.javasoft. com/products/jndi /tutorial/index.h tml</A>
<DD><A name=2>[2]</A> Novell Class Libraries for Java(including Novell
providers for JNDI), <A
href="../../developer.novell.com/ndk/doc/njcl/index.htm">http://developer.novell.com/ndk/doc/njcl/index.htm</A>
</DD></DL><A name=seven>七、范例程式完整內容</A>
<P align=center>
<TABLE width="70%">
<TBODY>
<TR>
<TD class=detail><PRE><CODE>
import javax.naming.*;//<A name=p1><FONT color=red>(1)</FONT>
import javax.naming.directory.*;//<FONT color=red>(1)</FONT>
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");//<A name=p2><FONT color=red>(2)</FONT>
env.put("java.naming.provider.url", "nds://NCLTREE/");//<FONT color=red>(2)</FONT>
/* Create the initial directory context. */
DirContext ctx = new InitialDirContext(env);//<A name=p3><FONT color=red>(3)</FONT>
/* Set up and perform the search. Find all people in NCL
whose common name starts with admin or Barabbas. */
String base = "o=NCL";//<A name=p4><FONT color=red>(4)</FONT>
String filter = "(|(cn=admin*)(cn=Barabbas*))";//<A name=p5><FONT color=red>(5)</FONT>
SearchControls constraints = new SearchControls();//<A name=p6><FONT color=red>(6)</FONT>
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);//<FONT color=red>(6)</FONT>
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());
}
}
}
</CODE></PRE></A></TD></TR></TBODY></TABLE></P>
<P align=center>
<TABLE width="70%">
<TBODY>
<TR>
<TD class=detail><PRE><CODE>
C:\javaset\jndi112>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;home\Barabbas
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
</CODE></PRE></TD></TR></TBODY></TABLE>
</table>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -