中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

上海網(wǎng)站備案北京發(fā)生大事了

上海網(wǎng)站備案,北京發(fā)生大事了,速橙科技有限公司網(wǎng)站建設(shè),牡丹江城鄉(xiāng)建設(shè)局網(wǎng)站命名和目錄操作 您可以使用JNDI執(zhí)行以下操作:讀取操作和更新命名空間的操作。本節(jié)介紹這兩個操作: l 查詢對象 l 列出上下文內(nèi)容 l 添加、覆蓋和移除綁定 l 重命名對象 l 創(chuàng)建和銷毀子上下文 配置 在命…

命名和目錄操作

您可以使用JNDI執(zhí)行以下操作:讀取操作和更新命名空間的操作。本節(jié)介紹這兩個操作:

l?????????查詢對象

l?????????列出上下文內(nèi)容

l?????????添加、覆蓋和移除綁定

l?????????重命名對象

l?????????創(chuàng)建和銷毀子上下文

配置

在命名和目錄服務(wù)中執(zhí)行操作之前,需要得到初始化上下文――命名空間的開始點(diǎn)。因為命名和目錄服務(wù)的所有方法都相對于一些上下文執(zhí)行。

為了得到初始化上下文,必須執(zhí)行以下步驟:

1.?????選擇想要訪問的訪問提供者。

2.?????指定需要的初始化上下文。

3.?????調(diào)用InitialContext構(gòu)造函數(shù)。

第一步:為初始化上下文選擇服務(wù)提供者

您可以為初始化上下文指定服務(wù)提供者,創(chuàng)建一個環(huán)境變量集合(Hashtable),同時將服務(wù)提供者的名稱加入其中。環(huán)境屬性在JNDI教程中有詳細(xì)的介紹。

如果您使用Sun的LDAP服務(wù)提供者,代碼如下所示:

?

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");

?

要指定Sun的文件系統(tǒng)服務(wù)提供者,代碼如下所示:

?

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory");

?

您可以使用一些系統(tǒng)屬性描述使用的服務(wù)提供者。在JNDI教程中有詳細(xì)描述。

第二步:提供初始化上下文需要的信息

不同目錄的客戶端可能需要提供不同的信息用來連接目錄。例如,您需要指定服務(wù)器運(yùn)行的機(jī)器以及識別目錄中的用戶。這些信息通過環(huán)境屬性傳遞給服務(wù)提供者。JNDI指定服務(wù)提供者使用的一般環(huán)境參數(shù)。您的服務(wù)提供者文檔會為需要提供的參數(shù)進(jìn)行詳細(xì)的說明。

LDAP提供者需要程序提供LDAP服務(wù)器的位置,以及認(rèn)證信息。要提供這些信息,需要如下代碼:

?

env.put(Context.PROVIDER_URL, "ldap://ldap.wiz.com:389");

env.put(Context.SECURITY_PRINCIPAL, "joeuser");

env.put(Context.SECURITY_CREDENTIALS, "joepassword");

?

本教程中使用Sun的LDAP服務(wù)提供者。例子中假設(shè)服務(wù)器設(shè)置在本機(jī),使用389端口,根辨別名是“o=JNDITutorial”,修改目錄不需要認(rèn)證。這些信息是設(shè)置環(huán)境所需要的。

?

env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

?

如果您使用不同設(shè)置的目錄,需要設(shè)置相應(yīng)的環(huán)境屬性。您需要使用機(jī)器名稱替換“l(fā)ocalhost”。您可以在任何公共的目錄服務(wù)器或在其他機(jī)器上的自己的服務(wù)器運(yùn)行例子。您需要將“l(fā)ocalhost”替換成那臺機(jī)器的名字,將o=JNDITutorial替換成相應(yīng)的命名上下文。

第三步:創(chuàng)建初始化上下文

您已經(jīng)創(chuàng)建了初始化上下文。為了做到這一點(diǎn),您將之前創(chuàng)建的環(huán)境屬性放到InitialContext構(gòu)造函數(shù)中:

?

Context ctx = new InitialContext(env);

?

現(xiàn)在您有了一個上下文對象的引用,可以開始訪問命名服務(wù)了。

為了完成目錄操作,需要使用InitialDirContext。為了做到這一點(diǎn),使用它的一個構(gòu)造函數(shù):

?

DirContext ctx = new InitialDirContext(env);

?

這句話返回了用來進(jìn)行目錄操作的DirContext對象引用。

命名異常

JNDI包中的很多方法當(dāng)拋出異常時,說明操作請求不能執(zhí)行。一般情況下,您將看到可以拋出NamingException的方法使用try/catch進(jìn)行包裝。

?

try {

????Context ctx = new InitialContext();

????Object obj = ctx.lookup("somename");

} catch (NamingException e) {

????// Handle the error

????System.err.println(e);

}

?

異常類結(jié)構(gòu)

JNDI有豐富的異常結(jié)構(gòu),所有異常都從NamingException類中繼承。異常類名都是自解釋的,在下文中進(jìn)行列舉。

如果要處理特定的NamingException子類,需要分別catch子類。例如,以下代碼特別的對待AuthenticationException及其子類。

?

try {

????Context ctx = new InitialContext();

????Object obj = ctx.lookup("somename");

} catch (AuthenticationException e) {

????// attempt to reacquire the authentication information

????...

} catch (NamingException e) {

????// Handle the error

????System.err.println(e);

}

?

枚舉

諸如Context.list()和DirContext.search()這種操作返回NamingEnumeration。在這些情況下,如果出現(xiàn)錯誤并且沒有返回結(jié)果,NamingException或它的子類會在方法請求時拋出。如果出現(xiàn)錯誤并且返回了部分結(jié)果,返回NamingEnumeration這樣您可以取得這些結(jié)果。當(dāng)所有結(jié)果都取出來后,再請求NamingEnumeration.hasMore()會導(dǎo)致拋出NamingException(或其子類)異常,表示出現(xiàn)錯誤。在這種情況下,枚舉變得非法并且不能再請求其中任何方法。

例如,如果執(zhí)行search()并且指定最多返回多少結(jié)果,那么search()最多返回n個結(jié)果。如果結(jié)果超過n個,那么當(dāng)?shù)趎+1次請求NamingEnumeration.hasMore()時,拋出SizeLimitExceededException。請參見本節(jié)中的有關(guān)limit的示例代碼。

本手冊中的例子

在本手冊文件中的在線示例代碼中,通常為了便于閱讀省略了try/catch語句。通常,因為只有部分代碼片段在這里展示,所以只展示直接表示概念的行。如果您查看本教程附帶的源碼文件,將看到try/catch語句的合適位置。

javax.naming包中異常在這里可以看到。

查詢對象

要從命名服務(wù)中查詢對象,使用Context.lookup()方法并且傳入您想取得的對象名。假設(shè)命名服務(wù)中有一個對象的名稱是cn=Rosanna Lee,ou=People。要取得這個對象,您只需要編寫:

?

Object obj = ctx.lookup("cn=Rosanna Lee,ou=People");

?

lookup()返回的對象類型依賴于命名服務(wù)以及對象關(guān)聯(lián)的數(shù)據(jù)。命名服務(wù)可以包含許多不同類型的對象,同時在系統(tǒng)的不同部分查詢的對象可能得到不同的類型。例如,“cn=Rosanna Lee,ou=People”綁定到上下文對象中(javax.naming.ldap.LdapContext)。您可以對lookup()方法的結(jié)果cast成需要的類。

例如,以下代碼查詢“cn=Rosanna Lee,ou=People”對象并且cast成LdapContext。

?

import javax.naming.ldap.LdapContext;

...

LdapContext ctx = (LdapContext) ctx.lookup("cn=Rosanna Lee,ou=People");

?

完整的例子在Lookup.java文件中。

在Java SE 6中查詢名稱引入了兩個新的靜態(tài)方法:

l?????????InitialContext.doLookup(Name name)

l?????????InitialContext.doLookup(String name)

?

這些方法提供了不實例InitialContext查找對象的快捷方式。

列舉上下文

代替Context.lookup()一次取得一個對象的方法,您可以在一個單一的操作中列舉整個剩下文。列舉上下文有兩個方法:一個返回了綁定關(guān)系,另一個只返回名-對象類型名。

Context.List()方法

Context.list()返回NameClassPair的枚舉。每個NameClassPair包含對象名和對象類型名。下列代碼列舉了“ou=People”目錄的內(nèi)容(例如,“ou=People”目錄中找到的文件和目錄)。

?

NamingEnumeration list = ctx.list("ou=People");

?

while (list.hasMore()) {

????NameClassPair nc = (NameClassPair)list.next();

????System.out.println(nc);

}

?

返回值如下:

?

# java List

cn=Jon Ruiz: javax.naming.directory.DirContext

cn=Scott Seligman: javax.naming.directory.DirContext

cn=Samuel Clemens: javax.naming.directory.DirContext

cn=Rosanna Lee: javax.naming.directory.DirContext

cn=Maxine Erlund: javax.naming.directory.DirContext

cn=Niels Bohr: javax.naming.directory.DirContext

cn=Uri Geller: javax.naming.directory.DirContext

cn=Colleen Sullivan: javax.naming.directory.DirContext

cn=Vinnie Ryan: javax.naming.directory.DirContext

cn=Rod Serling: javax.naming.directory.DirContext

cn=Jonathan Wood: javax.naming.directory.DirContext

cn=Aravindan Ranganathan: javax.naming.directory.DirContext

cn=Ian Anderson: javax.naming.directory.DirContext

cn=Lao Tzu: javax.naming.directory.DirContext

cn=Don Knuth: javax.naming.directory.DirContext

cn=Roger Waters: javax.naming.directory.DirContext

cn=Ben Dubin: javax.naming.directory.DirContext

cn=Spuds Mackenzie: javax.naming.directory.DirContext

cn=John Fowler: javax.naming.directory.DirContext

cn=Londo Mollari: javax.naming.directory.DirContext

cn=Ted Geisel: javax.naming.directory.DirContext

?

Context.listBindings()方法

Context.listBindings()方法返回綁定的枚舉。綁定是NameClassPair的子類。綁定不止包含對象名和對象類名,還包含對象。以下代碼片段枚舉了“ou=People”上下文,打印出每一個綁定名稱和對象。

?

NamingEnumeration bindings = ctx.listBindings("ou=People");

?

while (bindings.hasMore()) {

????Binding bd = (Binding)bindings.next();

????System.out.println(bd.getName() + ": " + bd.getObject());

}

?

返回的結(jié)果如下:

?

# java ListBindings

cn=Jon Ruiz: com.sun.jndi.ldap.LdapCtx@1d4c61c

cn=Scott Seligman: com.sun.jndi.ldap.LdapCtx@1a626f

cn=Samuel Clemens: com.sun.jndi.ldap.LdapCtx@34a1fc

cn=Rosanna Lee: com.sun.jndi.ldap.LdapCtx@176c74b

cn=Maxine Erlund: com.sun.jndi.ldap.LdapCtx@11b9fb1

cn=Niels Bohr: com.sun.jndi.ldap.LdapCtx@913fe2

cn=Uri Geller: com.sun.jndi.ldap.LdapCtx@12558d6

cn=Colleen Sullivan: com.sun.jndi.ldap.LdapCtx@eb7859

cn=Vinnie Ryan: com.sun.jndi.ldap.LdapCtx@12a54f9

cn=Rod Serling: com.sun.jndi.ldap.LdapCtx@30e280

cn=Jonathan Wood: com.sun.jndi.ldap.LdapCtx@16672d6

cn=Aravindan Ranganathan: com.sun.jndi.ldap.LdapCtx@fd54d6

cn=Ian Anderson: com.sun.jndi.ldap.LdapCtx@1415de6

cn=Lao Tzu: com.sun.jndi.ldap.LdapCtx@7bd9f2

cn=Don Knuth: com.sun.jndi.ldap.LdapCtx@121cc40

cn=Roger Waters: com.sun.jndi.ldap.LdapCtx@443226

cn=Ben Dubin: com.sun.jndi.ldap.LdapCtx@1386000

cn=Spuds Mackenzie: com.sun.jndi.ldap.LdapCtx@26d4f1

cn=John Fowler: com.sun.jndi.ldap.LdapCtx@1662dc8

cn=Londo Mollari: com.sun.jndi.ldap.LdapCtx@147c5fc

cn=Ted Geisel: com.sun.jndi.ldap.LdapCtx@3eca90

?

結(jié)束NamingEnumeration

NamingEnumeration可以通過三種方式終止:一般的,顯式的,非顯式的。

l?????????當(dāng)NamingEnumeration.hasMore()返回false,枚舉結(jié)束同時終止。

l?????????您可以在枚舉終止前請求NamingEnumeration.close()方法顯式的終止一個枚舉。這樣做提示底層實現(xiàn)釋放任何和枚舉有關(guān)的資源。

l?????????如果hasMore()或next()方法拋出任何異常,枚舉立即終止。

不管如何終止枚舉,枚舉一旦被終止就不能再使用。在一個已終止的枚舉中請求任何方法都會導(dǎo)致不確定的結(jié)果。

為什么使用兩個不同的方法?

list()為瀏覽類型的應(yīng)用程序準(zhǔn)備,只返回上下文中對象的名字。例如,瀏覽器可能列出上下文中的名字,期待用戶選擇一個或多個顯示的名稱來進(jìn)行后續(xù)操作。這些應(yīng)用程序一般不需要訪問上下文中所有的對象。

listBindings()為需要在上下文對象中進(jìn)行操作的應(yīng)用程序準(zhǔn)備。例如,備份程序需要在文件目錄中所有對象中執(zhí)行“file stats”操作?;蛘?#xff0c;一個打印機(jī)管理員程序可能想要重啟建筑物內(nèi)的所有打印機(jī)。為了執(zhí)行這些操作,需要得到上下文中的所有對象。因此,將對象作為枚舉的一部分返回是權(quán)宜之計。

應(yīng)用程序可以依據(jù)需要的信息類型選擇list()或listBindings()。

添加、替換、或刪除綁定

Context接口包含在上下文中添加、替換、刪除綁定的方法。

添加綁定

Context.bind()為了向上下文中添加綁定,它以對象類型以及需要綁定的對象作為參數(shù)。

?

在繼續(xù)前:本教程中的例子需要您對架構(gòu)做額外的修改。您必須關(guān)閉LDAP服務(wù)器的架構(gòu)檢測或?qū)⒎媳窘坛痰募軜?gòu)添加到服務(wù)器中。這種工作一般由目錄服務(wù)器管理員執(zhí)行。請看課程。

?

// Create the object to be bound

Fruit fruit = new Fruit("orange");

?

// Perform the bind

ctx.bind("cn=Favorite Fruit", fruit);

?

這個例子創(chuàng)建了一個Fruit類的對象同時在上下文ctx中將他綁定到名稱“cn=Favorite Fruit”中。如果您隨后在ctx中查詢“cn=Favorite Fruit”,那么您將得到fruit兌現(xiàn)。注意,編譯Fruit類需要FruitFactory類。

如果您運(yùn)行這個例子兩次,那么第二次會因為NameAlreadyBoundException異常失敗。因為“cn=Favorite Fruit”已經(jīng)綁定了。要第二次運(yùn)行時不失敗,需要使用rebind()。

添加或修改綁定

rebind()用來添加或替換綁定。它的參數(shù)列表和bind()一樣,但如果名稱已經(jīng)綁定,那么首先會unbound然后再重新綁定新的對象。

?

// Create the object to be bound

Fruit fruit = new Fruit("lemon");

?

// Perform the bind

ctx.rebind("cn=Favorite Fruit", fruit);

?

當(dāng)您運(yùn)行這個例子時,將會替換bind()例子中已經(jīng)創(chuàng)建的綁定關(guān)系。

刪除綁定

要刪除綁定,使用unbind()。

?

// Remove the binding

ctx.unbind("cn=Favorite Fruit");

?

當(dāng)這個例子運(yùn)行時,刪除bind()或unbind()創(chuàng)建的綁定關(guān)系。

重命名

您使用Context.rename()對上下文中的對象進(jìn)行重命名。

?

// Rename to Scott S

ctx.rename("cn=Scott Seligman", "cn=Scott S");

?

這個例子將綁定到“cn=Scott Seligman”的對象綁定到了“cn=Scott S”中。在驗證對象被重命名后,程序再將其重命名回原來的名字(“cn=Scott Seligman”),如下所示:

?

// Rename back to Scott Seligman

ctx.rename("cn=Scott S", "cn=Scott Seligman");

?

更多關(guān)于LDAP中重命名的例子請參考LDAP的高級注意。

創(chuàng)建和銷毀子上下文

Context接口包含創(chuàng)建和銷毀一個子上下文。子上下文是綁定到其他上下文的上下文。

這個例子使用一個有屬性的對象,然后在目錄中創(chuàng)建子上下文。您可以使用DirContext的方法將屬性和對象在綁定或子上下文添加到名字空間時進(jìn)行關(guān)聯(lián)。例如,您可以創(chuàng)建Person對象,然后在為Person對象關(guān)聯(lián)屬性的同時將他綁定到命名空間中。命名等于沒有任何屬性。

createSubcontext()和bind()不同,他創(chuàng)建了一個新對象,例如一個要綁定到目錄中的新上下文,但bind()在目錄中綁定了給定的對象。

?

創(chuàng)建上下文

要創(chuàng)建命名上下文,您向createSubcontext()提供要創(chuàng)建上下文的名稱。要創(chuàng)建有屬性的上下文,向DirContext.createSubcontext()提供想要創(chuàng)建上下文的名稱以及需要的屬性。

?

在繼續(xù)前:本教程中的例子需要您對架構(gòu)做額外的修改。您必須關(guān)閉LDAP服務(wù)器的架構(gòu)檢測或?qū)⒎媳窘坛痰募軜?gòu)添加到服務(wù)器中。這種工作一般由目錄服務(wù)器管理員執(zhí)行。請看課程。

?

// Create attributes to be associated with the new context

Attributes attrs = new BasicAttributes(true); // case-ignore

Attribute objclass = new BasicAttribute("objectclass");

objclass.add("top");

objclass.add("organizationalUnit");

attrs.put(objclass);

?

// Create the context

Context result = ctx.createSubcontext("NewOu", attrs);

?

這個例子創(chuàng)建了名稱為“ou=NewO”的上下文,并且有屬性“objectclass”,屬性“top”和“organizationalUnit”,其中“objectclass”有兩個值。

?

# java Create

ou=Groups: javax.naming.directory.DirContext

ou=People: javax.naming.directory.DirContext

ou=NewOu: javax.naming.directory.DirContext

?

這個例子創(chuàng)建了一個新的上下文,叫“NewOu”,是ctx的子上下文。

銷毀上下文

要銷毀上下文,需要向destroySubcontext()提供需要銷毀上下文的名稱。

?

// Destroy the context

ctx.destroySubcontext("NewOu");

?

這個例子在上下文ctx中刪除上下文“NewOu”。

屬性名

屬性由屬性標(biāo)識符和一組屬性值組成。屬性表示符叫屬性名,是表示屬性的字符串。屬性值是屬性的內(nèi)容,它的類型不一定是字符串。當(dāng)您想要指定獲取、搜索、或修改指定屬性時,您使用屬性名。名稱同時在返回屬性的操作中返回(例如,當(dāng)您執(zhí)行目錄的讀取或搜索操作時)。

當(dāng)使用屬性名時,您需要知道特定目錄服務(wù)器的特性,所以您不會為結(jié)果驚奇。這些特定在下一子節(jié)中描述。

屬性類型

在諸如LDAP之類的目錄中,屬性名表示了屬性的類型,通常叫做屬性類型名。例如,屬性名“cn”同時叫做屬性類型名。屬性類型定義了屬性值的語法,是否允許多值,相等性,以及對屬性值執(zhí)行比較和排序時的排序規(guī)則,

屬性子類

一些目錄實現(xiàn)支持目錄子類型,就是服務(wù)器允許屬性類型使用其他屬性類型定義。例如,“name”屬性可能是所有name相關(guān)屬性的超類型:“commonName”是name的子類。對于支持這種特斯娜格的目錄實現(xiàn),訪問“name”屬性可能返回“commonName”屬性。

當(dāng)訪問支持子類型的屬性的目錄時,要知道服務(wù)器可能返回和您請求不一致的類型。為了減少這種幾率,使用最派生類。

屬性名同義詞

一些目錄實現(xiàn)支持屬性名的同義詞。例如,“cn”可能是“commonName”的同義詞。所以請求“cn”屬性可能返回“commonName”屬性。

當(dāng)訪問支持屬性同義詞的目錄,您必須意識到服務(wù)器可能返回和您請求不同的屬性名。要防止這種情況發(fā)生,使用官方的屬性名代替使用同義詞。官方的屬性名是定義屬性的屬性名;同義詞是是定義中引用官方屬性名的名稱。

語言參數(shù)選擇

LDAP v3的擴(kuò)展(RFC 2596)允許您和屬性名一起指定語言編碼。類似于子類屬性,一個屬性名可以表示多個不同的屬性。例如“description”屬性有兩個不同的語言變體:

?

description: software

description;lang-en: software products

description;lang-de: Softwareprodukte

?

對“description”屬性的請求會返回所有三種屬性。當(dāng)訪問支持這種特性的目錄時,您必須意識到服務(wù)器可能返回和請求時不同的名稱。

讀取屬性

為了從目錄中讀取對象的屬性,使用DirContext.getAttributes()并且將您想讀取的屬性名稱傳遞進(jìn)去就可以了。假設(shè)在命名服務(wù)中的一個對象的名稱是“cn=Ted Geisel, ou=People”。要獲取對象的屬性要使用如下代碼:

?

Attributes answer = ctx.getAttributes("cn=Ted Geisel, ou=People");

?

您可以按照如下方式打印應(yīng)答的內(nèi)容:

?

for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {

????Attribute attr = (Attribute)ae.next();

????System.out.println("attribute: " + attr.getID());

????/* Print each value */

????for (NamingEnumeration e = attr.getAll(); e.hasMore();

?????System.out.println("value: " + e.next()))

????;

}

?

輸出如下:

?

# java GetattrsAll

attribute: sn

value: Geisel

attribute: objectclass

value: top

value: person

value: organizationalPerson

value: inetOrgPerson

attribute: jpegphoto

value: [B@1dacd78b

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: facsimiletelephonenumber

value: +1 408 555 2329

attribute: telephonenumber

value: +1 408 555 5252

attribute: cn

value: Ted Geisel

?

返回選中屬性

為了讀取選中子集的屬性,您需要提供想要獲取的屬性標(biāo)識符的數(shù)組。

?

// Specify the ids of the attributes to return

String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};

?

// Get the attributes requested

Attributes answer = ctx.getAttributes("cn=Ted Geisel, ou=People", attrIDs);

?

這個例子請求對象“cn=Ted Geisel, ou=People”的“sn”,“telephonenumber”,“golfhandicap”和“mail”屬性,所以應(yīng)答中返回這三個屬性。

以下是輸出結(jié)果:

?

# java Getattrs

attribute: sn

value: Geisel

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: telephonenumber

value: +1 408 555 5252

?

修改屬性

DirContext接口包含修改目錄中對象的屬性和屬性值的方法。

使用修改列表

修改對象屬性的一個方法是提供修改列表(ModificationItem)。每一個ModificationItem包含數(shù)字常量表示修改的類型以及描述需要修改的屬性。以下是修改的類型。

l?????????ADD_ATTRIBUTE

l?????????REPLACE_ATTRIBUTE

l?????????REMOVE_ATTRIBUTE

修改以列表中提供的類型進(jìn)行?;蛘咚械男薷亩紙?zhí)行,或者一個都不執(zhí)行。

以下代碼創(chuàng)建修改列表。它將“mail”屬性值替換成geisel@wizards.com,為“telephonenumber”屬性添加附加值,并且刪除“jpegphoto”屬性。

?

// Specify the changes to make

ModificationItem[] mods = new ModificationItem[3];

?

// Replace the "mail" attribute with a new value

mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,

????new BasicAttribute("mail", "geisel@wizards.com"));

?

// Add an additional value to "telephonenumber"

mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE,

????new BasicAttribute("telephonenumber", "+1 555 555 5555"));

?

// Remove the "jpegphoto" attribute

mods[2] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,

????new BasicAttribute("jpegphoto"));

?

Windows活動目錄:活動目錄將“telephonenumber”屬性定義為單值屬性,這和RFC 2256不符。為了讓這個例子在活動目錄中執(zhí)行,您必須或者使用其他屬性代替“telephonenumber”或?qū)irContext.ADD_ATTRIBUTE改為DirContext.REPLACE_ATTRIBUTE。

?

在創(chuàng)建修改列表后,您可以按照如下方式提供給modifyAttributes():

?

// Perform the requested modifications on the named object

ctx.modifyAttributes(name, mods);

?

使用屬性

可選的,您可以通過指定修改類型以及修改屬性的方式進(jìn)行修改。

例如,以下行使用orig中的name關(guān)聯(lián)需要替換的屬性:

?

ctx.modifyAttributes(name, DirContext.REPLACE_ATTRIBUTE, orig);

?

其他屬性的名稱沒有改變。

兩種對于modifyAttributes()的使用在示例程序中都有。使用修改列表修改屬性的程序在第二部分modifyAttributes()中恢復(fù)了原來的屬性。

有屬性的添加、刪除綁定

命名的例子討論如何使用bind()和unbind(),DirContext這兩方法的重載版本。您使用DirContext的方法關(guān)聯(lián)對象的屬性,在綁定或子上下文時將她們添加到名字空間中。例如,您可能創(chuàng)建了Person對象,然后在為Person對象關(guān)聯(lián)屬性時將他綁定到名字空間中。

添加有屬性的綁定

DirContext.bind()用來將屬性綁定添加到上下文中。它的參數(shù)為需要綁定的對象名稱, 以及屬性集合。

?

// Create the object to be bound

Fruit fruit = new Fruit("orange");

?

// Create attributes to be associated with the object

Attributes attrs = new BasicAttributes(true); // case-ignore

Attribute objclass = new BasicAttribute("objectclass");

objclass.add("top");

objclass.add("organizationalUnit");

attrs.put(objclass);

?

// Perform bind

ctx.bind("ou=favorite, ou=Fruits", fruit, attrs);

?

這個例子創(chuàng)建了Fruit類的對象并且將他綁定到“ou=Fruits”上下文中,名稱為“ou=favorite”。綁定有“objectclass”屬性。如果接下來在ctx中查詢“ou=favorite, ou=Fruits”,那么您將得到fruit對象。如果您想、得到“ou=favorite, ou=Fruits”的屬性,您將得到剛才為對象添加的屬性。以下是例子的輸出:

?

# java Bind

orange

attribute: objectclass

value: top

value: organizationalUnit

value: javaObject

value: javaNamingReference

attribute: javaclassname

value: Fruit

attribute: javafactory

value: FruitFactory

attribute: javareferenceaddress

value: #0#fruit#orange

attribute: ou

value: favorite

?

顯示的多于屬性使用來保存關(guān)于對象(fruit)的一些信息。這些多于信息隨后會進(jìn)行詳細(xì)介紹。

如果您兩次運(yùn)行這個例子,那么第二次運(yùn)行時將會失敗并拋出NameAlreadyBoundException。這是因為“ou=favorite”已經(jīng)綁定到上下文“ou=Fruits”中。如果要成功,需要使用rebind()。

替換有屬性的綁定

DirContext.rebind()的作用是添加或修改綁定以及屬性。它接受和bind()一樣的參數(shù)。然而,使用rebind()時如果名稱已經(jīng)存在,那么將會首先Unbind然后再綁定新的對象和屬性。

?

// Create the object to be bound

Fruit fruit = new Fruit("lemon");

?

// Create attributes to be associated with the object

Attributes attrs = new BasicAttributes(true); // case-ignore

Attribute objclass = new BasicAttribute("objectclass");

objclass.add("top");

objclass.add("organizationalUnit");

attrs.put(objclass);

?

// Perform bind

ctx.rebind("ou=favorite, ou=Fruits", fruit, attrs);

?

運(yùn)行這個例子時,它替換了bind()例子中創(chuàng)建的綁定關(guān)系。

?

# java Rebind

lemon

attribute: objectclass

value: top

value: organizationalUnit

value: javaObject

value: javaNamingReference

attribute: javaclassname

value: Fruit

attribute: javafactory

value: FruitFactory

attribute: javareferenceaddress

value: #0#fruit#lemon

attribute: ou

value: favorite

?

搜索

目錄提供的最有用的好處就是黃頁功能,或搜索服務(wù)。您可以組合一個包含條目屬性的查詢,然后提交查詢到目錄中。然后目錄返回滿足查詢的條目列表。例如,您可以訪問目錄,查詢出保齡球平均成績大于200的條目,或所有姓以“Sch”開頭的人。

DirContext接口提供查詢條目的方法,這些方法很復(fù)雜也很強(qiáng)大。搜索目錄的不同方面在以下章節(jié)中描述:

l?????????基本搜索

l?????????搜索過濾器

l?????????搜索控制

基本搜索

最簡單的查詢需需要您指定條目必須含有的屬性集合以及進(jìn)行查詢的目標(biāo)上下文。

以下代碼創(chuàng)建了屬性集合matchAttrs,其中有兩個屬性“sn”和“mail”。表名搜索條目必須有姓(sn)屬性,其值為“Geisel”,以及“mail”屬性可以是任意值。然后調(diào)用DirContext.search()查詢上下文“ou=People”中和matchAttrs匹配的條目。

?

// Specify the attributes to match

// Ask for objects that has a surname ("sn") attribute with

// the value "Geisel" and the "mail" attribute

Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case

matchAttrs.put(new BasicAttribute("sn", "Geisel"));

matchAttrs.put(new BasicAttribute("mail"));

?

// Search for objects that have those matching attributes

NamingEnumeration answer = ctx.search("ou=People", matchAttrs);

?

You can then print the results as follows.

while (answer.hasMore()) {

????SearchResult sr = (SearchResult)answer.next();

????System.out.println(">>>" + sr.getName());

????printAttrs(sr.getAttributes());

}

?

printAttrs()方法和getAttributes()方法打印出屬性集合類似。

返回結(jié)果如下:

?

# java SearchRetAll

>>>cn=Ted Geisel

attribute: sn

value: Geisel

attribute: objectclass

value: top

value: person

value: organizationalPerson

value: inetOrgPerson

attribute: jpegphoto

value: [B@1dacd78b

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: facsimiletelephonenumber

value: +1 408 555 2329

attribute: cn

value: Ted Geisel

attribute: telephonenumber

value: +1 408 555 5252

?

返回選中屬性

上一個例子返回滿足指定查詢條件條目的所有屬性。您可以通過向search()傳遞屬性標(biāo)識符數(shù)組的方式選擇想要包含在結(jié)果集中的屬性。在創(chuàng)建matchAttrs只有,您應(yīng)該創(chuàng)建屬性標(biāo)識符的數(shù)組,如下所示:

?

// Specify the ids of the attributes to return

String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};

?

// Search for objects that have those matching attributes

NamingEnumeration answer = ctx.search("ou=People", matchAttrs, attrIDs);

?

這個例子返回條目的屬性“sn”,“telephonenumber”,“golfhandicap”以及“mail”,其中條目有屬性“mail”并且“sn”屬性的值是“Geisel”。這個例子產(chǎn)生如下結(jié)果。(條目中沒有“golfhandicap”屬性,所以沒有返回)。

?

# java Search

>>>cn=Ted Geisel

attribute: sn

value: Geisel

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: telephonenumber

value: +1 408 555 5252

?

過濾器

除了使用指定屬性集合進(jìn)行搜索外,您可以用搜索過濾器的形式進(jìn)行搜索。搜索過濾器是一種搜索用的邏輯表達(dá)式。DirContext.search()可接受的過濾器語法在RFC 2254中定義。

以下搜索過濾器指定了滿足查詢條件的條目必須有值為“Geisel”的“sn”屬性,以及值為任意的“mail”屬性:

?

(&(sn=Geisel)(mail=*))

?

以下代碼創(chuàng)建了過濾器以及默認(rèn)的SearchControls,使用他們執(zhí)行查詢。這個查詢的結(jié)果和基本查詢中的一致。

?

// Create the default search controls

SearchControls ctls = new SearchControls();

?

// Specify the search filter to match

// Ask for objects that have the attribute "sn" == "Geisel"

// and the "mail" attribute

String filter = "(&(sn=Geisel)(mail=*))";

?

// Search for objects using the filter

NamingEnumeration answer = ctx.search("ou=People", filter, ctls);

?

搜索結(jié)果如下:

?

# java SearchWithFilterRetAll

>>>cn=Ted Geisel

attribute: sn

value: Geisel

attribute: objectclass

value: top

value: person

value: organizationalPerson

value: inetOrgPerson

attribute: jpegphoto

value: [B@1dacd75e

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: facsimiletelephonenumber

value: +1 408 555 2329

attribute: cn

value: Ted Geisel

attribute: telephonenumber

value: +1 408 555 5252

?

搜索過濾器語法概述

搜索過濾器是前綴標(biāo)記的搜索表達(dá)式(邏輯運(yùn)算符在表達(dá)式前面)。下表列舉了創(chuàng)建過濾器使用的符號。

?

符號

描述

&

與(列表中所有項必須為true)

|

或(列表中至少一個必須為true)

!

非(求反的項不能為true)

=

相等(根據(jù)屬性的匹配規(guī)則)

~=

近似等于(根據(jù)屬性的匹配規(guī)則)

>=

大于(根據(jù)屬性的匹配規(guī)則)

<=

小于(根據(jù)屬性的匹配規(guī)則)

=*

存在(條目中必須有這個屬性,但值不做限制)

*

通配符(表示這個位置可以有一個或多個字符),當(dāng)指定屬性值時用到

\

轉(zhuǎn)義符(當(dāng)遇到“*”,“(”,“)”時進(jìn)行轉(zhuǎn)義)

?

過濾器中的每一個條目使用屬性標(biāo)識符和屬性值或符號表示屬性值組成。例如,項“sn=Geisel”表示“sn”屬性的值必須為“Geisel”,同時項“mail=*”表示“mail”屬性必須存在。

每項必須包含在括號之內(nèi),例如“(sn=Geisel)”。這些項使用邏輯運(yùn)算符,例如&,創(chuàng)建邏輯表達(dá)式,例如“(& (sn=Geisel) (mail=*))”。

每一個邏輯表達(dá)式可以進(jìn)一步組成其他項,例如“(| (& (sn=Geisel) (mail=*)) (sn=L*))”。這個例子請求的條目中或者含有值為“Geisel”的“sn”屬性和“mail”屬性或者“sn”屬性以字母“L”開頭。

關(guān)于語法的詳細(xì)描述,請參考RFC 2254。

返回選中屬性

上一個例子返回滿足指定過濾器的條目中的所有屬性。您可以通過設(shè)置搜索控制參數(shù)的方法選擇返回屬性。您創(chuàng)建想要包含在結(jié)果中的屬性標(biāo)識符集合,然后將他傳遞到SearchControls.setReturningAttributes()中。如下所示:

?

// Specify the ids of the attributes to return

String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};

SearchControls ctls = new SearchControls();

ctls.setReturningAttributes(attrIDs);

?

這個例子和基本搜索一節(jié)中返回選擇的屬性部分的結(jié)果一致。運(yùn)行后的結(jié)果如下。(這個條目沒有“golfhandicap”屬性,所以沒有返回)。

?

# java SearchWithFilter

>>>cn=Ted Geisel

attribute: sn

value: Geisel

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: telephonenumber

value: +1 408 555 5252

?

范圍

默認(rèn)的SearchControls指定搜索只在命名空間中進(jìn)行(SearchControls.ONELEVEL_SCOPE)。這個默認(rèn)選項在搜索過濾器一節(jié)中使用。

除了默認(rèn)選項之外,您可以指定搜索在整個子樹或只在命名對象中執(zhí)行。

搜索子樹

對于整個子樹的搜索不但搜索命名對象而且搜索它的后代。要按照這種方式進(jìn)行搜索,按照下面的方式向SearchControls.setSearchScope()中傳遞SearchControls.SUBTREE_SCOPE參數(shù):

?

// Specify the ids of the attributes to return

String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};

SearchControls ctls = new SearchControls();

ctls.setReturningAttributes(attrIDs);

ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

?

// Specify the search filter to match

// Ask for objects that have the attribute "sn" == "Geisel"

// and the "mail" attribute

String filter = "(&(sn=Geisel)(mail=*))";

?

// Search the subtree for objects by using the filter

NamingEnumeration answer = ctx.search("", filter, ctls);

?

這個例子搜索了ctx上下文的子樹,得到滿足搜索過濾器的條目。它在子樹中找到了滿足過濾器的“cn= Ted Geisel, ou=People”條目。

?

# java SearchSubtree

>>>cn=Ted Geisel, ou=People

attribute: sn

value: Geisel

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: telephonenumber

value: +1 408 555 5252

?

搜索命名對象

您也可以搜索命名對象。這樣做是很有用的,例如,測試命名對象是否滿足搜索過濾器。為了搜索命名對象,將SearchControls.OBJECT_SCOPE傳遞到setSearchScope()中。

?

// Specify the ids of the attributes to return

String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};

SearchControls ctls = new SearchControls();

ctls.setReturningAttributes(attrIDs);

ctls.setSearchScope(SearchControls.OBJECT_SCOPE);

?

// Specify the search filter to match

// Ask for objects that have the attribute "sn" == "Geisel"

// and the "mail" attribute

String filter = "(&(sn=Geisel)(mail=*))";

?

// Search the subtree for objects by using the filter

NamingEnumeration answer =

????ctx.search("cn=Ted Geisel, ou=People", filter, ctls);

?

這個例子測試是否對象“cn=Ted Geisel, ou=People”滿足給定的過濾器。

?

# java SearchObject

>>>?

attribute: sn

value: Geisel

attribute: mail

value: Ted.Geisel@JNDITutorial.com

attribute: telephonenumber

value: +1 408 555 5252

?

例子找到了一個結(jié)果并進(jìn)行打印。注意結(jié)果中的名稱字段為空。因為對象的名稱是進(jìn)行查詢的上下文(cn=Ted Geisel, ou=People)。

結(jié)果數(shù)量

有時,查詢可能返回了太多的結(jié)果同時您想限制結(jié)果集的大小。這時您可以使用限制數(shù)量的搜索控制。默認(rèn)情況下,搜索沒有數(shù)量限制――它將會返回找到的所有結(jié)果。要設(shè)置搜索的數(shù)量限制,將數(shù)字傳遞到SearchControls.setCountLimit()中。

以下例子設(shè)置數(shù)量限制為1。

?

// Set the search controls to limit the count to 1

SearchControls ctls = new SearchControls();

ctls.setCountLimit(1);

?

如果程序嘗試得到更多的結(jié)果,那么會拋出SizeLimitExceededException。如果程序設(shè)置數(shù)量限制,那么或者將這個異常和NamingExceptions異常區(qū)別對待或者按照數(shù)量限制的大小,不請求超過數(shù)量的結(jié)果。

滿足搜索數(shù)量限制是控制程序消耗資源的一種方法(例如內(nèi)存和網(wǎng)絡(luò)帶寬)。其他控制資源的方法是盡量使用小的搜索過濾器,在合適的上下文中開始搜索,使用合適的范圍。

時間限制

搜索時間限制是搜索操作等待應(yīng)答的時間上限。當(dāng)您不想為應(yīng)答等待太長時間時這很有用。如果搜索操作超過時間限制還沒完成,那么將會拋出TimeLimitExceededException異常。

為了設(shè)置搜索的時間限制,將毫秒數(shù)傳遞到SearchControls.setTimeLimit()即可。以下例子將時間限制設(shè)置為1秒。

?

// Set the search controls to limit the time to 1 second (1000 ms)

SearchControls ctls = new SearchControls();

ctls.setTimeLimit(1000);

?

要讓這個例子運(yùn)行超時,需要重新配置,或者使用一個慢的服務(wù)器或這使用有很多條目的服務(wù)器。您還可以使用其他方式讓搜索超過1秒。

時間限制為0表示不進(jìn)行時間限制,這樣請求將會進(jìn)行無限等待。

常見問題解答

當(dāng)您使用JNDI類運(yùn)行成功編譯的程序時可能遇到的主要問題如下:

?

l?????????沒有初始化上下文

l?????????連接被拒絕

l?????????連接失敗

l?????????程序掛起

l?????????名字沒有找到

l?????????不能連接任意主機(jī)

l?????????不能配置訪問系統(tǒng)屬性

l?????????不能使用CRAM-MD5認(rèn)證

?

1.????得到NoInitialContextException

原因:您沒有指定使用的初始化上下文。特別的,Context.INITIAL_CONTEXT_FACTORY環(huán)境變量沒有設(shè)置成為初始化上下文的工廠類名。后者,找不到Context.INITIAL_CONTEXT_FACTORY配置的可得到的服務(wù)提供者。

解決方案:將環(huán)境變量Context.INITIAL_CONTEXT_FACTORY設(shè)置為您使用的初始化上下文類名。詳細(xì)信息請參考配置一節(jié)。

如果屬性已經(jīng)設(shè)置,那么確認(rèn)類名沒有輸入錯誤,并且類在您的程序中可見(或者在classpath中或者在JRE的jre/lib/ext目錄下)。Java平臺包含服務(wù)提供者有LDAP,COS命名,DNS以及RMI注冊。所有其他的服務(wù)提供者必須安裝并且添加到執(zhí)行環(huán)境中。

2.????得到CommunicationException異常,表示“連接被拒絕”。

原因:Context.PROVIDER_URL環(huán)境參數(shù)表示的服務(wù)器和端口沒有提供訪問。可能有人禁用或關(guān)閉了服務(wù)?;蛘咻斎肓隋e誤的服務(wù)器名稱或端口號。

解決方案:檢查端口上確實運(yùn)行了服務(wù),如果需要就重啟服務(wù)器。這種檢查依賴于您使用的LDAP服務(wù)器。通常,可以使用管理控制臺或工具管理服務(wù)器。您可以使用工具確認(rèn)服務(wù)器的狀態(tài)。

3.????LDAP服務(wù)器向其他工具應(yīng)答(例如管理控制臺)但不應(yīng)答您程序的請求。

原因:服務(wù)器沒有應(yīng)答LDAP v3的連接全逆光球。一些服務(wù)器(尤其是公共服務(wù)器)不能正確的應(yīng)答LDAP v3,使用忽略的方式代替拒絕。同時,一些LDAP v3服務(wù)器有錯誤處理機(jī)制,Sun的LDAP服務(wù)提供者自動發(fā)送并且通常返回特定服務(wù)器錯誤碼。

解決方案:嘗試設(shè)置環(huán)境參數(shù)“java.naming.ldap.version”為“2”。LDAP服務(wù)提供者默認(rèn)嘗試使用LDAP v3連接LDAP服務(wù)器,然后使用LDAP v2。如果服務(wù)器靜默忽略v3的請求,那么提供者假設(shè)請求生效了。使用這種服務(wù)器,您必須顯式的設(shè)置協(xié)議版本,確保服務(wù)器有正確的行為。

如果服務(wù)器是v3服務(wù)器,那么嘗試在創(chuàng)建初始化上下文之前設(shè)置這些環(huán)境參數(shù):

?

env.put(Context.REFERRAL, "throw");

?

這樣關(guān)閉了LDAP提供者自動發(fā)送的控制(更多信息請參考JNDI教程)。

4.????程序掛起。

原因:當(dāng)您嘗試執(zhí)行的查實會生成太多結(jié)果或需要服務(wù)器查詢很多條目才能生成結(jié)果時,服務(wù)器(尤其是公共的)不應(yīng)答(不是一個失敗應(yīng)答)。這種服務(wù)器基于預(yù)請求計算花費(fèi)的方式嘗試減少資源消耗。

或者,您嘗試使用安全套接字層(SSL)但服務(wù)器/端口不支持,反之(您嘗試使用普通套接字與SSL端口對話)。

最終,服務(wù)器或者因為負(fù)載原因非常慢的應(yīng)答,或完全不應(yīng)答某些請求。

解決方案:如果程序因為服務(wù)器為了減少資源消耗而掛起,那么重試請求會得到單一應(yīng)答或只有很少的應(yīng)答。這樣可以幫助您判斷服務(wù)器是否還在活動。這樣,您可以加寬原有查詢,重新發(fā)送。

如果您的程序因為SSL問題掛起,那么您需要找到SSL端口然后正確設(shè)置Context.SECURITY_PROTOCOL環(huán)境參數(shù)。如果端口是SSL端口,那么這個參數(shù)應(yīng)該設(shè)置成“ssl”。如果不是SSL端口,這個參數(shù)不應(yīng)該設(shè)置。

如果程序不是因為上述原因掛起,使用com.sun.jndi.ldap.read.timeout表示讀取超時。這個參數(shù)的值是一個字符串,表示LDAP請求讀取超時的毫秒數(shù)。如果LDAP提供者不能在周期內(nèi)得到應(yīng)答,那么放棄讀取嘗試。數(shù)字應(yīng)該大于0。等于或小于0表示不指定讀取超時時間,等于無限等待得到應(yīng)答。

如果沒有指定這個參數(shù),默認(rèn)情況下會一直等待,直到得到應(yīng)答。

例如:

?

env.put("com.sun.jndi.ldap.read.timeout", "5000");

?

表示如果LDAP服務(wù)器不能在5秒中內(nèi)應(yīng)答,將放棄讀取請求。

5.????您得到NameNotFoundException異常。

原因:當(dāng)您為LDAP初始化了初始上下文,提供了根辨別名。例如,如果您為初始上下文設(shè)置Context.PROVIDER_URL為“l(fā)dap://ldapserver:389/o=JNDITutorial”,然后提供名稱“cn=Joe,c=us”,那么您向LDAP服務(wù)傳遞的全名為“cn=Joe,c=us,o=JNDITutorial”。如果這確實是您想要的名稱,那么您應(yīng)該檢驗服務(wù)器確定包含這個條目。

同時,如果您在認(rèn)證時提供錯誤的辨別名,Sun Java目錄服務(wù)器返回錯誤。例如,如果您設(shè)置Context.SECURITY_PRINCIPAL?環(huán)境參數(shù)為“cn=Admin, o=Tutorial”,并且“cn=Admin, o=Tutorial”不是LDAP服務(wù)器的條目,LDAP提供者將要拋出NameNotFoundException。Sun Java目錄服務(wù)器返回的實際上是一些認(rèn)證異常,不是“name not found”。

解決方案:確認(rèn)您提供的名字是服務(wù)器上存在的。您可以通過列舉父上下文的所有條目或使用其他工具例如服務(wù)器的管理員控制臺來確認(rèn)。

?

以下是在部署applet時可能遇到的問題。

?

6.????當(dāng)您的applet嘗試連接目錄服務(wù)器時得到AppletSecurityException異常,服務(wù)器正運(yùn)行在和下載applet不同的機(jī)器上。

原因:applet沒有簽名,所以只能連接到加載它的機(jī)器。或者,如果appet已經(jīng)簽名,瀏覽器沒有授予applet連接目錄服務(wù)器的權(quán)限。

解決方案:如果您想允許applet連接任意機(jī)器上的目錄服務(wù)器,那么需要簽名整個applet以及applet使用的JNDI jar。關(guān)于jar的簽名,請參考簽名和驗證jar文件。

7.????當(dāng)您的applet嘗試使用系統(tǒng)屬性設(shè)置環(huán)境屬性時出現(xiàn)AppletSecurityException異常。

原因:瀏覽器限制訪問系統(tǒng)參數(shù),并且當(dāng)您嘗試讀取時拋出SecurityException。

解決方案:如果您需要為applet得到輸入,嘗試使用applet params代替。

8.????當(dāng)applet運(yùn)行在Firefox中嘗試使用CRAM-MD5向LDAP進(jìn)行認(rèn)證時拋出AppletSecurityException。

原因:Firefox禁止訪問java.security包。LDAP提供者使用java.security.MessageDigest提供的信息摘要功能來實現(xiàn)CRAM-MD5。

解決方案:使用Java插件。

?


轉(zhuǎn)自:https://blog.csdn.net/liumm0000/article/details/7932019

http://m.risenshineclean.com/news/58270.html

相關(guān)文章:

  • 怎么設(shè)計頁面只顯示一頁說說seo論壇
  • 病毒推廣網(wǎng)站網(wǎng)絡(luò)營銷怎么做
  • wordpress 全景插件軟件排名優(yōu)化
  • 手機(jī)網(wǎng)站模板更換方法sem網(wǎng)站推廣怎么做
  • 辦公用品網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣企業(yè)
  • 有了php源碼怎么做網(wǎng)站公司網(wǎng)絡(luò)推廣排名定制
  • 網(wǎng)站的競價怎么做軟件培訓(xùn)機(jī)構(gòu)排名
  • 怎么用ngrok做網(wǎng)站百度品牌廣告收費(fèi)標(biāo)準(zhǔn)
  • 網(wǎng)站開發(fā)的就業(yè)前景如何沈陽網(wǎng)站制作公司
  • 做茶評的網(wǎng)站谷歌seo排名優(yōu)化服務(wù)
  • 哪些購物網(wǎng)站做的比較簡潔有品質(zhì)手機(jī)端網(wǎng)站優(yōu)化
  • 設(shè)計業(yè)務(wù)網(wǎng)站競價是什么意思
  • 網(wǎng)站建設(shè)推廣新聞成都疫情最新情況
  • 安徽服飾網(wǎng)站建設(shè)萬網(wǎng)域名官網(wǎng)
  • 淘寶網(wǎng)網(wǎng)站開發(fā)今日頭條新聞軍事
  • wordpress 怎么上傳文件到根目錄網(wǎng)站優(yōu)化培訓(xùn)班
  • 免費(fèi)網(wǎng)站建設(shè)信息搜狐綜合小時報2022113011
  • 做網(wǎng)站app免費(fèi)的行情軟件app網(wǎng)站
  • 品牌網(wǎng)站怎么做一網(wǎng)信息一個簡單便捷的新聞網(wǎng)站
  • 網(wǎng)站數(shù)據(jù)庫5g北京百度網(wǎng)站排名優(yōu)化
  • 吉林網(wǎng)站建設(shè)業(yè)務(wù)日本shopify獨(dú)立站
  • 微信公眾號 視頻網(wǎng)站開發(fā)網(wǎng)絡(luò)營銷推廣流程
  • 搬瓦工vps做網(wǎng)站速度怎么樣營銷方案怎么寫
  • 超級簡歷模板官網(wǎng)北京seo公司公司
  • 做餐飲網(wǎng)站建設(shè)下載谷歌瀏覽器并安裝
  • 網(wǎng)站營銷外包如何做網(wǎng)推技巧
  • 網(wǎng)站開發(fā)的小結(jié)騰訊營銷平臺
  • 邢臺網(wǎng)站建設(shè)免費(fèi)做網(wǎng)站排名seo關(guān)鍵詞布局案例
  • 網(wǎng)站平臺是怎么做財務(wù)的贛州網(wǎng)站seo
  • 網(wǎng)站建設(shè)屬政府采購項目嗎濟(jì)寧百度推廣公司