Interstage ディレクトリサービスに対してエントリの検索を要求すると、検索条件に合致したエントリの情報が通知されます。エントリを検索するには、以下のメソッドを使用します。
javax.naming.DirContext.search()
基本的な検索は、サーチベースと検索フィルタを指定します。検索フィルタには、検索条件の式を指定します。たとえば、「sn」属性の値が「Fujitsu」で、「mail」属性の値が「.fujitsu.com」で終わるものを検索するとき、次の式を指定します。
(&(sn=Fujitsu)(mail=*.fujitsu.com))
検索例です。
String filter = "(&(sn=Fujitsu)(mail=*.fujitsu.com))";
NamingEnumeration results = ctx.search("ou=User,ou=interstage,o=fujitsu,dc=com", filter, null);
検索フィルタ式の詳細は、“7.1.2 検索フィルタ”を参照してください。
検索時には、検索対象の絞込みや、検索結果の待ち時間を指定することができます。これらの検索オプションについて、次項で説明します。
javax.naming.directory.SearchControlsを使用すると、以下の検索オプションを指定できます。
検索対象とする範囲
検索結果として取得する属性
検索結果の最大エントリ数
検索結果の最大待ち時間
検索対象とする範囲
検索対象とする範囲を絞り込むことができます。setSearchScope()メソッドを使用します。以下の3つの中から1つを指定します。初期値はONELEVEL_SCOPEです。
OBJECT_SCOPE : サーチベースに指定された階層だけを検索します。
ONELEVEL_SCOPE : サーチベースに指定された階層の1つ下の階層を検索します。
SUBTREE_SCOPE : サーチベースに指定された階層以下すべてを検索します。

サーチベースに指定した階層以下すべてを検索するときの指定例です。
SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
検索結果として取得する属性
基本的な検索では、読み取れる属性値すべての情報が返されます。アプリケーションの処理内容によって、必要な属性だけを取得することができます。setReturningAttributes()メソッドを使用します。検索結果として取得する属性名を配列で指定します。初期値はnull(すべての属性を返す)です。何も取得しないときは、空の配列を指定します。
「mail」と「telephonenumber」を取得するときの例です。
String[] attrs = {"mail", "telephonenumber"};
SearchControls constraints = new SearchControls();
constraints.setReturningAttributes(attrs);
検索結果の最大エントリ数
検索結果として受け取るエントリ数を制限できます。setCountLimit()メソッドを使用します。初期値は0(制限しない)です。
10件で制限する例です。
SearchControls constraints = new SearchControls(); constraints.setCountLimit(10);
検索結果の最大待ち時間
検索での待ち時間を制限できます。setTimeLimit()メソッドを使用します。待ち時間をミリ秒単位で指定します。初期値は0(制限しない)です。
1秒で制限する例です。
SearchControls constraints = new SearchControls(); constraints.setTimeLimit(1000);
![]()
クライアントからアクセスするDN(バインドDN)と、サーバ側の検索可能最大エントリ数、検索タイムアウト時間の指定値の組み合わせによっては、検索オプションで指定した値が有効にならない場合があります。クライアント側の指定値とサーバ側の指定値との関係は、Interstage管理コンソールのヘルプを参照してください。
javax.naming.DirContext.search()メソッドの復帰値は、NamingEnumerationで、SearchResultの列挙です。検索結果を表示するには、たとえば以下のようにします。
NamingEnumeration results = ctx.search("ou=User,ou=interstage,o=fujitsu,dc=com",
filter, constraints);
while (results != null && results.hasMore()) {
SearchResult si = (SearchResult)results.next();
System.out.println("name: " + si.getName());
Attributes attrs = si.getAttributes();
if (attrs == null) {
System.out.println("No attributes");
} else {
/* print each attribute */
for (NamingEnumeration ae = attrs.getAll();
ae.hasMoreElements(); ) {
Attribute attr = (Attribute)ae.next();
String id = attr.getID();
/* print each value */
for (Enumeration vals = attr.getAll();
vals.hasMoreElements();
System.out.println(id + ": " + vals.nextElement()));
}
}
}
バイナリ属性値の取得
バイナリ属性値は、byte[]で受け取ります。また、デフォルトでは、以下の属性がバイナリ値として返されます。
audio
jpegPhoto
javaSerializedData
userPassword
userCertificate
cACertificate
authorityRevocationList
certificateRevocationList
crossCertificatePair
バイナリ属性値を表示する例です。
NamingEnumeration results = ctx.search("ou=User,ou=interstage,o=fujitsu,dc=com",
filter, constraints);
while (results != null && results.hasMore()) {
SearchResult si = (SearchResult)results.next();
Attributes attrs = si.getAttributes();
if (attrs == null) {
System.out.println("No attributes");
} else {
/* print each attribute */
for (NamingEnumeration ae = attrs.getAll();
ae.hasMoreElements(); ) {
Attribute attr = (Attribute)ae.next();
String id = attr.getID();
/* print each value */
for (Enumeration vals = attr.getAll();
vals.hasMoreElements(); ) {
System.out.print( id + ": " );
Object val = vals.nextElement();
if (val instanceof String) {
System.out.println( val );
} else {
byte[] buf = (byte[])val;
for (int i = 0; i < buf.length; i++) {
System.out.print(Integer.toHexString(buf[i]) + " ");
}
}
System.out.println();
}
}
}
}
スキーマ拡張をして、文字列ではない属性構文を定義したときは、環境プロパティ「java.naming.ldap.attributes.binary」を使って、バイナリ値として返されるように指定します。例を示します。
env.put("java.naming.ldap.attributes.binary","mpegVideo myspecialkey");検索結果の取得とコネクションの累積
検索結果をすべて取り出していない場合、または検索結果を破棄していない場合には、セションをクローズしても、すぐにはUNBINDが送出されません。以下のタイミングでコネクションが破棄されるまで、クライアントおよびサーバ間でコネクションが累積されます。
アプリケーションの終了時にJava VMが呼び出すfinalize()の契機
検索結果の変数の参照が無効になり、Java VMのガーベジコレクションが実行される契機
コネクションが累積されると、サーブレットでJNDIを動作させる場合や、コネクションの生成、破棄を繰り返すプログラムでは、Interstage ディレクトリサービスにつながらないといった問題を引き起こす可能性があります。
コネクションが累積されないようにするためには、以下のどちらかの方法で検索結果をクリアし、確実にUNBINDが送出されるようにしてください。
検索結果をすべて取り出す
DirContext ctx = new InitialDirContext(env);
NamingEnumeration results = ctx.search("dc=com", "cn=User001", constraints);
while (results != null && results.hasMore()){
SearchResult sr = (SearchResult)results.next();
}
検索結果を破棄する
DirContext ctx = new InitialDirContext(env);
NamingEnumeration results = ctx.search("dc=com", "cn=User001", constraints);
results.close();