Java之JNDI詳解

來源:互聯網
上載者:User

標籤:地址   手工   一個   基礎   6.4   增加   顯示   網域名稱   換行   

轉載自(http://blog.csdn.net/u010430304/article/details/54601302)

JNDI的基本應用 
        JNDI是Java Naming and Directory Interface(JAVA命名和目錄介面)的英文簡寫,它是為JAVA應用程式提供命名和目錄訪問服務的API(Application Programing Interface,API)。

1.命名的概念與應用 
        JNDI中的命名(Naming),就是將Java對象以某個名稱的形式綁定(binding)到一個容器環境(Context)中,以後調用容器環境(Context)的尋找(lookup)方法又可以尋找出某個名稱所綁定的Java對象。讀者也許會感到奇怪:自己建立一個Java對象,將其綁定到JNDI容器環境中後又查詢出來,這有什麼意思?在真實的項目應用中,通常是由系統程式或框加程式先將資來源物件綁定到JNDI環境中,以後在該系統或架構中啟動並執行模組程式就可以從JNDI環境中尋找這些資來源物件了。例如,Tomcat伺服器在啟動時可以建立一個串連到某種資料庫系統的資料來源(DataSource)對象,並將該資料來源(DataSource)對象綁定到JNDI環境中,以後在這個Tomcat伺服器中啟動並執行Servlet和JSP程式就可以從JNDI環境中查詢出這個資料來源(DataSource)對象進行使用,而不用關心資料來源(DataSource)對象是如何建立出來的,這種方式極大地增強了系統的可維護性,當資料庫系統的串連參數發生變更時,這隻是Tomcat系統管理員一個人要關心的事情,而與所有的應用程式開發人員無關。 
        容器環境(Context)本身也是一個Java對象,它也可以通過一個名稱綁定到另一個容器環境(Context)中。將一個Context對象綁定到另外一個Context對象中,這就形成了一種父子級聯關係,多個Context對象最終可以級聯成一種樹狀結構,樹中的每個Context對象中都可以綁定若干個Java對象,6.10所示。 
 
圖6.10 
        圖6.10中的每個方框分別代表一個Context對象,它們綁定的名稱分別為a、b、c、d、e,b和c是a的子Context,d是b的子Context,e又是d的子Context。圖9.x中的各個方框內的每個小橢圓分別代表一個Java對象,它們也都有一個綁定的名稱,這些綁定名稱分別為dog、pig、sheet等,在同一個Context不能綁定兩個相同名稱的Java對象,在不同的Context中可以出現同名的綁定對象。可見,Context樹的級連接構與檔案系統中的目錄結構非常類似,Context與其中綁定的Java對象的關係也非常類似於檔案系統中的目錄與檔案的關係。從圖6.10中可以看到,要想得到Context樹中的一個Java對象,首先要得到其所在的Context對象,只要得到了一個Context對象,就可以調用它的查詢(lookup)方法來獲得其中綁定的Java對象。另外,調用某個Context對象的lookup方法也可以獲得Context樹中的任意一個Context對象,這隻需要在lookup方法中指定相應的Context路徑即可。在JNDI中不存在著“根”Context的概念,也就是說,執行JNDI操作不是從一個“根”Context對象開始,而是可以從Context樹中的任意一個Context開始。無論如何,程式必須獲得一個作為操作入口的Context對象後才能執行各種JNDI命名操作,為此,JNDI API中提供了一個InitialContext類來建立用作JNDI命名操作的入口Context對象。Context是一個介面,Context對象實際上是Context的某個實作類別的執行個體對象,選擇這個具體的Context實作類別並建立其執行個體對象的過程是由一個Context工廠類來完成的,這個工廠類的類名可以通過JNDI的環境屬性java.naming.factory.initial指定,也可以根據Context的操作方法的url參數的Schema來選擇。

2.目錄的概念與應用 
        JNDI中的目錄(Directory)與檔案系統中的目錄概念有很大的不同,JNDI中的目錄(Directory)是指將一個對象的所有屬性資訊儲存到一個容器環境中。JNDI的目錄(Directory)原理與JNDI的命名(Naming)原理非常相似,主要的區別在於目錄容器環境中儲存的是對象的屬性資訊,而不是對象本身,所以,目錄提供的是對屬性的各種操作。事實上,JNDI的目錄(Directory)與命名(Naming)往往是結合在一起使用的,JNDI API中提供的代表目錄容器環境的類為DirContext,DirContext是Context的子類,顯然它除了能完成目錄相關的操作外,也能完成所有的命名(Naming)操作。DirContext是對Context的擴充,它在Context的基礎上增加了對目錄屬性的操作功能,可以在其中綁定對象的屬性資訊和尋找對象的屬性資訊。JNDI中的目錄(Directory)的結構6.11所示。 
 
圖6.11 
        圖6.11中的每個最外層的方框分別代表一個DirContext對象,它們綁定的名稱分別為a、b,b是a的子DirContext。圖6.11中的各個最外層的方框內的每個小橢圓分別代表一個Java對象,各個裡層的方框分別代表一個對象的屬性。從名稱為a的DirContext中的內容可以看到,一個DirContext容器環境中即可以綁定對象自身,也可以綁定對象的屬性資訊,綁定的對象和綁定的屬性是完全獨立的兩個事物,即使它們的綁定名稱相同,它們的操作也是完全獨立的。另外,一個屬性可以有多個屬性值,例如,dog對象的category屬性就設定了兩個屬性值:meat和pet。從名稱為b的DirContext中的內容可以看到,一個DirContext容器環境中也可以只綁定對象的屬性資訊,而不綁定任何對象自身。與Context的操作原理類似,JNDI API中提供了一個InitialDirContext類來建立用作JNDI命名與目錄屬性操作的入口DirContext對象。

3. 用於DNS查詢的JNDI服務程式 
        JNDI API是面嚮應用程式開發人員的編程介面,它在運行時需要調用某個具體的JNDI服務程式,JNDI API與JNDI服務程式之間的關係,猶如JDBC與JDBC驅動程式之間的關係。從JDK 1.3開始,JDK中就整合了JNDI API,從JDK 1.4開始的版本又整合了用於DNS查詢的JNDI服務程式,所以,如果我們使用JDK 1.4及更高的JDK版本來開發DNS資訊查詢程式時,不需要下載和安裝JNDI API和用於DNS查詢的JNDI服務程式。SUN公司提供的用於查詢DNS資訊的JNDI服務程式,將某個網域名稱的DNS資訊以屬性的形式綁定到代表該網域名稱的DirContext對象上。開啟JDK協助文檔的首頁,在其中搜尋“jndi”關鍵字,可以看到一條“jndi”的超連結,單擊這個超連結,就可以進入“Java Naming and Directory Interface”的協助頁面,6.12所示。 
 
圖6.12 
        單擊圖6.12中的“The DNS Service Provider”超連結,進入DNS服務程式的協助頁面。只要我們具備JDNI編程的一些基本知識,再加上該協助文檔頁提供的資訊,我們就知道如何調用這個DNS服務程式來獲得某個域的DNS資訊和MX記錄了。

        下面編寫一個實驗性的JNDI程式,這個程式用於協助我們熟悉和掌握JNDI API的使用,也協助我們瞭解DNS的JNDI服務程式以怎樣的形式返回DNS資訊。

動手實踐:使用JNDI API擷取DNS資訊 
        按常式6-5編寫一個名為DNSQuery.java的程式,這個程式使用JNDI API來獲得某個域的DNS資訊,並從中提取出域的一台SMTP伺服器的名稱,其中的很多代碼都是為了協助我們熟悉JNDI API的使用和瞭解DNS的JNDI服務程式返回的DNS資訊內容而加入的。運行這個程式時,需要指定一個或兩個參數,第一個參數是必須的,為要查詢的網域名稱,第二個參數是可選的,為查詢時所使用的DNS伺服器的IP地址,如果沒有指定第二個參數,DNS的JNDI服務程式將使用底層作業系統上設定的DNS伺服器。

常式6-5 DNSQuery.java

import java.util.Hashtable;import javax.naming.Context;import javax.naming.NamingEnumeration;import javax.naming.NamingException;import javax.naming.directory.Attribute;import javax.naming.directory.Attributes;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;public class DNSQuery {    public static void main(String[] args) throws NamingException     {        /*第一個參數指定要查詢的域或主機名稱,第二個參數指定查詢的DNS伺服器,        為了程式的簡單易讀性,省略了嚴格的參數錯誤檢查*/        String domain = args[0];        String dnsServer = args.length<2 ? "" : ("//" + args[1]);        //通過環境屬性來指定Context的工廠類        Hashtable env = new Hashtable();        env.put(Context.INITIAL_CONTEXT_FACTORY,                     "com.sun.jndi.dns.DnsContextFactory");        env.put(Context.PROVIDER_URL, "dns:" + dnsServer);        DirContext ctx = new InitialDirContext(env);        //分別擷取包含所有屬性和只包含Mx屬性的Attributes對象        Attributes attrsAll = ctx.getAttributes(domain);            Attributes attrsMx = ctx.getAttributes(domain, new String[]{"MX"});         /*上面的整段程式碼也可以用下面這段程式碼來替代,下面這段程式        代碼通過查詢URL中的Schema資訊來自動選擇Context的工廠類*/        /*        DirContext ctx = new InitialDirContext();        Attributes attrsAll = ctx.getAttributes("dns:" + dnsServer + "/" + domain);        Attributes attrsMx = ctx.getAttributes(            "dns:" + dnsServer + "/" + domain, new String[]{"MX"});                 */        System.out.println("列印出域" + domain +                                 "的Attributes對象中的資訊:");        System.out.println(attrsAll);        System.out.println("--------------------------");        System.out.println("列印只檢索域" + domain +                                 "的MX記錄的Attributes對象:");             System.out.println(attrsMx);        System.out.println("--------------------------");        System.out.println("逐一列印出Attributes對象中的各個屬性:");                 NamingEnumeration attributes = attrsAll.getAll();        while(attributes.hasMore())         {               System.out.println(attributes.next());        }        System.out.println("--------------------------");        //直接調用get方法從attrsMx集合檢索MX屬性        System.out.println("直接檢索Attributes對象中的MX屬性:");              Attribute attrMx = attrsAll.get("MX");        System.out.println(attrMx);         System.out.println("--------------------------");                   //擷取Mx屬性中的第一個值:        System.out.println("擷取Mx屬性中的第一個值:");        String recordMx = (String)attrMx.get();        System.out.println(recordMx);        //從Mx屬性的第一個值中提取郵件伺服器地址        System.out.println("從MX屬性值中提取的郵件伺服器地址:");        String smtpServer = recordMx.substring(                            recordMx.indexOf(" ") + 1);        System.out.println(smtpServer);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

(2)在Windows命令列視窗中編譯DNSQuery.java程式後,接著在命令列視窗中執行如下命令:

ipconfig /all
  • 1

如果ipconfig命令顯示的結果中包含有DNS Server的資訊,那麼我們接著就可以使用如下命令來啟動執行DNSQuery類:

java  DNSQuery  sina.com 
  • 1

上面的命令的運行結果6.13。 
 
圖6.13 
()假設在上一步用ipconfig命令查看到的本機電腦上配置的DNS Server為202.106.46.151,那麼,我們接著執行如下命令:

java  DNSQuery  sina.com  202.106.46.151
  • 1

這個命令執行完後,也能顯示出圖6.13中的資訊。我們接著故意將上面命令中的DNS伺服器參數指定為一個錯誤的IP地址進行執行,修改後的命令語句如下所示:

java  DNSQuery  sina.com  192.168.1.151
  • 1

這個命令執行完後的結果6.14所示: 
 
圖6.14 
如果電腦只能通過Proxy 伺服器串連到Internet,那麼在該電腦上直接執行如下命令:

java  DNSQuery  sina.com 
  • 1

這也將導致圖6.14中的錯誤。如果要想在通過Proxy 伺服器上網的情況下,正確執行上面的程式,可以採用如下命令:

java -DsocksProxyHost=162.105.1.200 -DsocksProxyPort=808 DNSQuery  sina.com  202.106.46.151
  • 1

由於上面的命令太長,在排版時分成了兩行來書寫,讀者在輸入上面這條命令時,不要手工換行。讀者應該根據自己的實際情況,修改其中的Proxy 伺服器地址、代理連接埠號碼和DNS伺服器的地址。

Java之JNDI詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.