• 締切済み

LDAPにアクセスしてNamingEnumerationが遅延する

お世話になります。 初めてLDAPにアクセスしたのですが、特定の検索条件の際にNamingEnumerationをhasMoreする所が遅延します。 *遅い時は2秒ほど掛かります。 同じ現象になって修正した方がいましたら、ご教授お願い致します。 ■ソース(見づらくてすいません) //LDAP接続設定 Hashtable env = new Hashtable(); DirContext ctx = new InitialDirContext(env); //取得属性 String str = ''; SearchControls cons = new SearchControls(); cons.setSearchScope(SearchControls.SUBTREE_SCOPE); cons.setReturningObjFlag(true); cons.setReturningAttributes(str); //検索条件 String filter = ""; NamingEnumeration res = ctx.search(base, filter, cons); while (res.hasMore()) { SearchResult entry = (SearchResult) res.next(); Attributes attrs = entry.getAttributes(); for (int i = 0; i < str.length; i++) { Attribute attr = attrs.get(str[i]); System.out.print((String) attr.get()); } System.out.println(); } よろしくお願い致します。

  • Java
  • 回答数1
  • ありがとう数2

みんなの回答

回答No.1

LDAPは、5、6年くらい前に使ってました。懐かしい。 とりあえず↓の部分ですが、falseをセットしてください。 cons.setReturningObjFlag(true); これは、SearchResultからDirContextオブジェクトを取得する時に使うもので、属性しか使用しないのであれば不要です。 ↓こんなことをやりたい場合ね。 SearchResult entry = (SearchResult) res.next(); DirContext dc = (DirContext) entry.getObject(); SearchResultオブジェクトからもgetNameInNamespace()で名前空間が取得できるし、DirContextオブジェクトから相対指定で属性取得等の操作ができるので、ベースとなるDirContextオブジェクトが一つあれば、他のオブジェクトは基本的に不要だと思います。 あと、取得したい属性が限定されているのであれば(というか限定するべき)、SearchControlsに取得属性を設定するべきです。 ↓こんな感じで。 cons.setReturningAttributes(new String[]{"cn", "uid"}); さらに件数が決まっている場合は、setCountLimit()で件数を限定するとより早くなります。

k_tanpin
質問者

お礼

miyachocom様。 ご回答ありがとうございます。 属性取得のみの場合は、 cons.setReturningObjFlag(false); にするのですね。 取得する属性は、String[]で渡しました。 しかし、データ件数6件の場合 NamingEnumeration res = ctx.search(base, filter, cons); は0.1秒ほどなのですが while (res.hasMore()) の所が2秒かかる場合があります。 これは、LDAPアクセスの問題では無くて、javaの問題だと思うのですが こんな現象になった事は無いですか? 説明下手で申し訳ありません。 宜しくお願い致します。

関連するQ&A

  • LDAPのコネクションが切れません

    すいません、、何方か知っている方がいましたらご教授下さい。 アプリ環境:windows2003 Websphere v5.1 JDK 1.4.2 LDAP環境:AIX5 OpenLDAP の環境で、javaからLDAPにアクセスするロジックを作成中です。 アクセスは出来るのですが、コネクションがclose()を使っても切れません。 ガベージコレクションで切れる事はわかったのですが、何かほかの方法はないでしょうか?よろしくお願いいたします。 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; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; public class LdapDAO { private Hashtable env; private DirContext ctx = null; public LdapDAO() throws NamingException { String url = "ldap://172.22.1.85:389"; String auth = "simple"; String base = "ou=people,dc=com"; String user = "***"; String pass = "***"; env = new Hashtable(); env.put( Context.INITIAL_CONTEXT_FACTORY, cf); env.put( Context.PROVIDER_URL, url); env.put("java.naming.ldap.version", "3"); env.put( Context.SECURITY_AUTHENTICATION, auth); env.put( Context.SECURITY_PRINCIPAL, user); env.put( Context.SECURITY_CREDENTIALS, pass); env.put("com.sun.jndi.ldap.connect.timeout", "3000"); env.put("com.sun.jndi.ldap.connect.pool", "true"); env.put("com.sun.jndi.ldap.connect.pool.timeout", "2000"); } public String searchEmpAll(String employeeNumber, String flg) throws NamingException { String result = ""; ctx = new InitialDirContext(env); SearchControls cons = new SearchControls(); cons.setSearchScope(SearchControls.SUBTREE_SCOPE); cons.setReturningObjFlag(true); cons.setReturningAttributes(new String[]{****}); String filter = "****"; NamingEnumeration res = ctx.search(base, filter, cons); for(int i = 0; res.hasMore(); i++) { SearchResult entry = (SearchResult) res.next(); Attributes attrs = entry.getAttributes(); Attribute attribute = attrs.get(*****); if(attribute != null) { result = (String) attribute.get(); } } cons = null; res = null; ctx.close(); // System.gc(); return result; } }

    • ベストアンサー
    • Java
  • メソッドの分割(リファクタリング?)

    指導教官からプログラム自体には問題はないが長すぎるのでメソッドを分割したほうがよいといわれました。以下に書きます(一部改変) try{ System.out.println("1. 2. どちらかを選択してください"); InputStreamReader reader = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(reader); String str = br.readLine(); int res = Integer.parseInt(str); if(!str.matches("[1-2]+")){ System.out.println("1、2から選択してください。"); continue;} if(res == 1){ System.out.println("キーワードを入力"); reader = new InputStreamReader(System.in); br = new BufferedReader(reader); str = br.readLine(); String sql = "SQL文"; ResultSet result = stmt.executeQuery(sql); //vectorにデータを格納 Vector vector1 = new Vector(); String[] array1 = new String[2]; while(result.next()){ array1[0] = result.getString("Res1"); array1[1] = result.getString("Res2"); vector1.addElement(array1); array1 = new String[2];} for(int i = 0;i < vector1.size();i++ ){ String Res1 = null;  String Res2 = null; String[] str1 = (String[])vector1.get(i); Res1 = str1[0]; Res2 = str1[1]; System.out.println("Res1,Res2は" + Res1 + "\t" + Res2);}} if(res == 2){1と同様なので省略・・}} catch(IOException e){ System.out.println(e + "例外が発生しました");} }} メソッドの分割のコツはあるのでしょうか?お勧めの本はございますか? 長くてすいません。

    • ベストアンサー
    • Java
  • stringのreplace

    import java.io.*; public class ex51c { public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while(true) { System.out.print("String> "); String str= in.readLine(); if(str.equals("")) { break; } String res = ""; res =str.replace('a', '*') returns str.replace('e', '*') returns str.replace('i', '*') returns str.replace('o', '*') returns str.replace ('u', '*'); System.out.println(res); } } } このようなプログラムを作ってみたのですが、 コンパイル時にエラーが出ます。 どこを直せばいいのでしょうか。教えてください。

    • ベストアンサー
    • Java
  • C#のListの要素がHashtableの並べ替え

    Listの要素がHashtableなのですが、Hashtableの特定のキーでListを並べ替える事ができるでしょうか? 例えば次の様な場合 int[] pid = new int[] { 2, 1, 3 }; string [] pname = new string[] { "田中", "鈴木", "本田" }; string[] pref = new string[] { "埼玉", "群馬", "千葉" }; int[] presult = new int[] { 65, 38, 52 }; List<object> usertList = new List<object>(); for (int i = 0; i <= 2; ++i) { Hashtable t_obj = new Hashtable(); t_obj["pid"] = pid[i]; t_obj["pname"] = name[i]; t_obj["pref"] = pref[i]; t_obj["presult"] = presult[i]; usertList.Add(t_obj); } usertListを pidに従って並べ替える presultに従って並べ替える presultとpidに従って並べ替える という事を行いたいのですが、どうすればよいか分かりません。 申し訳ありませんが、教えていただけないでしょうか?

  • HashMapについて

    質問させてください 以下に簡単なコードをJBuilderで作成しました。 printでブレークをはってmapインスタンスを評価してみると、mapに20個のキーが登録されるはずが、 16個しかいません。 この時点でstr1[16]が評価しても表示されていないのですが、map.get()で正常に取得はできています。 どのようなことが考えられるか、わかる型がいましたら教えてください。よろしくお願いいたします。 import java.util.*; class Test { public static void main(String[]args){ HashMap map = new HashMap(); String str1[] = new String[20]; String str2[] = new String[20]; for(int i = 0; i < 20; i ++){ str1[i] = new String(Integer.toString(i)); str2[i] = new String(Integer.toString(i * 10)); map.put(str1[i],str2[i]); } System.out.println("デバック用ブレーク"); System.out.println(map.get(str1[11])); } }

    • ベストアンサー
    • Java
  • Javaで配列を定義する方法

    こんにちは、片岡といいます。 Java言語で配列を定義する場合、以下の二つの書式に違いはありますか。 違いがあるとすれば、どのような違いですか。 また、違いがないのならば、どちらの記述がよいのですか。 ご存知の方はいらっしゃいませんか。 (1) public class Main1 { public static void main(String[] args) { String str[] = new String[] { new String("itiban"), new String("niban"), new String("sanban"), }; for (int i = 0; i < str.length; i++ ) { System.out.println(str[i]); } } } (2) public class Main2 { public static void main(String[] args) { String str[] = { new String("itiban"), new String("niban"), new String("sanban"), }; for (int i = 0; i < str.length; i++ ) { System.out.println(str[i]); } } } なお、私の環境は以下の通りです。 OS: Microsoft Windows XP Professional SP2 java: java version "1.4.2_13" 検索エンジンで"配列 オブジェクト java"を検索しましたが、 解決に役立つ情報は見つかりませんでした。

    • ベストアンサー
    • Java
  • インスタンスの作成について

    下記の方法にてHashtableのインスタンスを作成しようと思ったのですが has1.put("key",1); の場所でNullpointerException が発生します。 has1がNullになってしまうのですが 下記のような手法でインスタンスは作れないのでしょうか。 public class InstanceCreate { Hashtable has1; Hashtable has2; Hashtable has3; public static void main(String[] args) { InstanceCreate instance = new InstanceCreate(); instance.exe(); } public void exe() { Hashtable hash[] = {has1,has2,has3}; for(int i=0; i<hash.length;i++){ hash[i] = new Hashtable(); hash[i].put("key", "value"); } has1.put("key",1); } }

    • ベストアンサー
    • Java
  • スレッドについて(長文です)

    現在スレッドについて独学しています。array[0]に文字列を格納してそれを表示し、3秒間経った後に他のスレッドに通知し繰り返すというプログラムを作りたいのですが、以下のソースでコンパイルすると 5行目 型の開始が不正です  try{ ^ 6行目 <identifier>がありません  } ^ 18行目 シンボルを解釈処理できません シンボル:メソッドres(java.lang.String) 位置:Proのクラス pro.res(str2); ^ というコンパイルエラーがでます。模範解答と見比べてもかなりの部分が違います。このやり方では実現できないのでしょうか?なにぶん初心者なもので正しい答えとかけ離れた次元のプログラムを書いているかもしれませんがよろしくお願いします。 class Pro extends Thread{ String str; String array[] = new String[1]; try{ synchronized void res(String str){ this.str = str; array[0] = str; System.out.println(array[0]); Thread.sleep(((int)(Math.random() * 10) * 50) + 500); array[0] = "empty"; Thread.sleep(3000); notifyAll(); } } catch(Exception e1){ e1.printStackTrace(); } } class User extends Thread{ String str2; Pro pro; User(String str2,Pro pro){ this.str2 = str2; this.pro = pro; } public void run(){ while(true){ try{ if((pro.array[0]).equals("empty")){ pro.res(str2); } else{ wait(); } } catch(Exception e2){ e2.printStackTrace(); } } } } class NewRikai6{ public static void main(String args[]){ Pro pro = new Pro(); User user1 = new User("user1",pro); user1.start(); User user2 = new User("user2",pro); user2.start(); } }

    • ベストアンサー
    • Java
  • javaについて

    キーボードから入力をして、その後str[0][0]とstr[1][0]の文字を繋げたいのですがエラーとなってしまいます。どう変えたらよいでしょうか。 以下がプログラムです。 import java.io.*; import java.lang.*; import java.net.*; import java.awt.*; class gugu3 { public static void main(String[] args) throws IOException { int KEYWORDMAX=10; int CNTMAX=100; String [][]str = new String[KEYWORDMAX][CNTMAX]; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line=null; for (int i=0;i<KEYWORDMAX;i++){ System.out.println("第"+(i+1)+"番目のキーワードを設定しますか?(y/n)"); line=br.readLine(); if(line.equals("n")) break; for (int s=0;s<CNTMAX;s++){ System.out.println("キーワードを入力してください(終了=0)"); line=br.readLine(); if(line.equals("0"))break; str[s][i]=line; } } String keyword = new String(str[0][0]" "str[1][0]); System.out.println("キーワードは "+keyword); } } 以下はエラー表示です。 gugu3.java:24: ')' がありません。 String keyword = new String(str[0][0]" "str[1][0]); ^ gugu3.java:24: 文ではありません。 String keyword = new String(str[0][0]" "str[1][0]); ^ gugu3.java:24: ';' がありません。 String keyword = new String(str[0][0]" "str[1][0]); ^ エラー 3 個

    • ベストアンサー
    • Java
  • CSVファイルを二次元配列に格納するプログラム

    整数のCSVファイルを読み込んで、int型の二次元配列に格納するプログラムを作成中なのですが どうもうまくいきません。 String Str = ""; try { File inFile = new File("./res/test.csv"); FileReader fr = new FileReader(inFile); BufferedReader br = new BufferedReader(fr); ArrayList<String[]> al = new ArrayList<String[]>(); while (br.ready()) { Str = br.readLine(); al.add(Str.split(",")); } int[][] im = new int[al.size()][]; for (int i = 0; i < al.size(); i++) { im[i] = (int)al.get(i); // ここでエラー } br.close(); fr.close(); } catch (Exception e) { System.out.println("ファイル読み込みに関するエラー"); } 他にいい方法ありませんか? また逆で、int型配列に格納されているデータをCSVファイルとして出力する方法もお願いします