Java JNDI ldap递归搜索

Java JNDI ldap递归搜索,java,ldap,jndi,openldap,Java,Ldap,Jndi,Openldap,有人能帮我改进java中的ldap递归搜索吗?下面是我的代码。我要传递的过滤器是filter=(&(IMSI=40420123450021))。目前,从100000条记录中搜索一条记录需要19秒以上的时间 public List<Map<String, String>> searchRecursive(List<String> sColumns, Map<String, String> searchFilters, int startIndex,

有人能帮我改进java中的ldap递归搜索吗?下面是我的代码。我要传递的过滤器是
filter=(&(IMSI=40420123450021))
。目前,从100000条记录中搜索一条记录需要19秒以上的时间

public List<Map<String, String>> searchRecursive(List<String> sColumns, Map<String, String> searchFilters, int startIndex,
        int amount)
{
    String searchRDN = "";
    List<Map<String, String>> items = new ArrayList<Map<String, String>>();
    Attributes searchAttributes = new BasicAttributes();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    NamingEnumeration<SearchResult> results = null;
    try
    {
             String filter = "";
             if (searchFilters != null)
             {
                 for (Map.Entry<String, String> entry : searchFilters.entrySet())
                 {
                     filter += "(" + entry.getKey() + "=" + entry.getValue() + ")";
                 }
             }    
            filter = "(&" + filter + ")";
            _log.debug("filter="+filter);
            byte[] cookie = null;
            ctx.setRequestControls(new Control[]
                {new PagedResultsControl(amount, cookie, Control.NONCRITICAL)});

           //results = ctx.search(searchRDN, searchAttributes, null);
            results= ctx.search("", filter, ctls);
        if (results != null)
        {
            while (results.hasMore())
            {
                Map<String, String> rowSet = new CaseInsensitiveMap();
                SearchResult searchResult = results.next();
                String rdn = searchResult.getNameInNamespace();
                rowSet.put("baseRDN", rdn);
                NamingEnumeration<? extends Attribute> all = searchResult.getAttributes().getAll();
                while (all.hasMoreElements())
                {
                    Attribute attr = all.nextElement();
                    // attr.getID()
                    NamingEnumeration<?> all2 = attr.getAll();
                    String value = "";
                    while (all2.hasMoreElements())
                    {
                        if (!value.equals(""))
                        {
                            value += ", " + all2.nextElement();
                        }
                        else
                        {
                            value = "" + all2.nextElement();
                        }
                    }
                    rowSet.put(attr.getID(), value);
                }
                items.add(rowSet);
            }
        }
    }
    catch (Throwable e)
    {
        _log.error(e.getMessage());
        _log.debug(e);
    }
    finally
    {
        if (results != null)
        {
            try
            {
                results.close();
            }
            catch (Exception e)
            {
            }
        }
    }
    return items;
}
public List searchRecursive(List sColumns、Map searchFilters、int startIndex、,
整数金额)
{
字符串searchRDN=“”;
列表项=新建ArrayList();
Attributes searchAttributes=新的基本属性();
SearchControls ctls=新的SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_范围);
NamingEnumeration结果=空;
尝试
{
字符串过滤器=”;
if(searchFilters!=null)
{
for(Map.Entry:searchFilters.entrySet())
{
过滤器+=”(“+entry.getKey()+”=“+entry.getValue()+”);
}
}    
filter=“(&“+filter+”);
_log.debug(“filter=“+filter”);
字节[]cookie=null;
ctx.setRequestControls(新控件[]
{new PagedResultsControl(amount,cookie,Control.NONCRITICAL)});
//results=ctx.search(searchRDN,searchAttributes,null);
结果=ctx.search(“,filter,ctls);
如果(结果!=null)
{
while(results.hasMore())
{
Map rowSet=new caseinsensitiviemap();
SearchResult SearchResult=results.next();
字符串rdn=searchResult.getNameInNamespace();
rowSet.put(“baseRDN”,rdn);
namingumeration all2=attr.getAll();
字符串值=”;
while(所有2.hasMoreElements())
{
如果(!value.equals(“”)
{
值+=”,“+all2.nextElement();
}
其他的
{
value=“”+all2.nextElement();
}
}
rowSet.put(attr.getID(),value);
}
items.add(行集);
}
}
}
捕获(可丢弃的e)
{
_log.error(例如getMessage());
_log.debug(e);
}
最后
{
如果(结果!=null)
{
尝试
{
结果:关闭();
}
捕获(例外e)
{
}
}
}
退货项目;
}

根据LDAP树和数据结构,以下一个或多个提示可能有用:

  • 从特定的
    ou=
    开始搜索,而不是从根开始,并减少搜索深度

    ctx.search(“,filter,ctls”)中替换
    带有DN,如
    ou=people,ou=company,ou=com

  • 限制搜索结果的大小

    通过
    ctls.setCountLimit(预期)添加搜索结果大小

  • 限制收集的属性

    添加一组您感兴趣的属性

    String[]attributeFilter={“cn”,“mail”};
    设置返回属性(attributeFilter)

  • 编辑以解释1

    LDAP结构类似于一棵树:

    root
     +- dc=com
      +- dc=company
       +- dc=people
        +- ou=developer
         +- dn=john_doe
        +- ou=manager
         +- dn=jane_foo
    
    如果您正在搜索
    john_doe
    请在
    ou=developer、ou=people、ou=company、ou=com
    而不是
    root
    (在代码中用
    表示)开始递归搜索

    编辑基于评论的示例

    root
     +- dc=com
      +- dc=example
       +- IMSI=1
        +- IMSI=1
         +- Context-Identifier=1001
    

    这个数据结构在我看来很奇怪。但根据这些信息,搜索应从
    IMSI=1、dc=example、dc=com开始,具体取决于LDAP树和数据结构,以下一个或多个提示可能有用:

  • 从特定的
    ou=
    开始搜索,而不是从根开始,并减少搜索深度

    ctx.search(“,filter,ctls”)中替换
    带有DN,如
    ou=people,ou=company,ou=com

  • 限制搜索结果的大小

    通过
    ctls.setCountLimit(预期)添加搜索结果大小

  • 限制收集的属性

    添加一组您感兴趣的属性

    String[]attributeFilter={“cn”,“mail”};
    设置返回属性(attributeFilter)

  • 编辑以解释1

    LDAP结构类似于一棵树:

    root
     +- dc=com
      +- dc=company
       +- dc=people
        +- ou=developer
         +- dn=john_doe
        +- ou=manager
         +- dn=jane_foo
    
    如果您正在搜索
    john_doe
    请在
    ou=developer、ou=people、ou=company、ou=com
    而不是
    root
    (在代码中用
    表示)开始递归搜索

    编辑基于评论的示例

    root
     +- dc=com
      +- dc=example
       +- IMSI=1
        +- IMSI=1
         +- Context-Identifier=1001
    

    这个数据结构在我看来很奇怪。但根据这些信息,搜索应从
    IMSI=1开始,dc=example,dc=com

    你能解释一下你的代码在做什么以及为什么要这样做吗?我想在所有对象类中搜索一个记录条目。有三个对象类你能解释一下你的代码在做什么以及为什么要这样做吗?我想在所有对象类中搜索一个记录条目。有三个对象类你能解释一下你的代码是什么吗我想在所有对象类中搜索一个记录条目。有三个对象类[root@localhost~]#grep“rootdn”/usr/local/etc/openldap/slapd.conf#对rootdn的更新。(例如,“通过*读取访问”)#rootdn始终可以读取和写入所有内容!rootdn“cn=Manager,dc=example,dc=com”#明文密码,特别是对于rootdn,应该[root@localhost~]#但是当我在ctx.search中添加这个时,我得到了错误代码32-没有这样的对象rootDN就像一个root用户。此DN将用于验证您的连接并在LDAP实例上搜索。我会在回答中更好地解释它。实际上我是ldap新手。你能帮我找到值吗