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();