简体   繁体   English

分页搜索返回的结果数量不正确

[英]Paged search returning incorrect amount of results

Tried implementing the page results control to my code to get past the 1000 users limit but it only returns as many users as I've set the page size to (eg page size is set to 20, it will only return 20 users). 尝试对我的代码实施页面结果控件以超过1000个用户限制,但它只会返回与我将页面大小设置为的用户数相同的用户(例如,页面大小设置为20,则只会返回20个用户)。 If I set the page size to over 1000, it will still max out at 1000. 如果我将页面大小设置为1000以上,则仍将最大为1000。

Here's my current code: 这是我当前的代码:

public void setupStupidConnection()
{   
String ldapURL = "ldap://myldapurl";
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put("com.sun.jndi.ldap.read.timeout", "10000");

env.put(Context.SECURITY_PRINCIPAL,"username");
env.put(Context.SECURITY_CREDENTIALS,"password");

//connect to my domain controller
env.put(Context.PROVIDER_URL,ldapURL);
}

public void stupidSearch(String searchOptions)
{
String tempString = "";

try
{
    LdapContext ctx = new InitialLdapContext(env,null);
      // Activate paged results
    int pageSize = 20;
    byte[] cookie = null;
    ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize,
        Control.NONCRITICAL) });
    int total;

    //Specify the attributes to return
    String returnedAtts[]={"Name", "samAccountName", "mail", "UserAccountControl", "distinguishedName"};
    searchCtls.setReturningAttributes(returnedAtts);

    //Specify the search scope
    searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    //specify the LDAP search filter
    String searchFilter;
    if(!"".equals(search))
    {
        switch(searchOptions)
        {
            case "Starts with...":
               searchFilter = "(&(objectClass=user) (objectCategory=person) (CN=" + search + "*))";    
            break;
            case "Ends with...":
               searchFilter = "(&(objectClass=user) (objectCategory=person) (CN=*" + search + "))";
            break;
            case "Contains...":
               searchFilter = "(&(objectClass=user) (objectCategory=person) (CN=*" + search + "*))";
            break;
            case "Equals...":
               searchFilter = "(&(objectClass=user) (objectCategory=person) (CN=" + search + "))";
            break;
            default:
               searchFilter = "(&(objectClass=user) (objectCategory=person) (CN=" + search + "*))"; 
            break;
        }
    }
    else
    {
        searchFilter = "(&(objectClass=user) (objectCategory=person))";
    }

    //Specify the Base for the search
    String searchBase;
    switch(searchPath)
    {
        case "A":
            searchBase = "OU=Accounts1";
        break;
        case "B":
            searchBase = "OU=Accounts2";
        break;
        case "C":
            searchBase = "OU=Accounts3";
        break;
        case "D":
            searchBase = "OU=Accounts4";
        break;
        default:
            searchBase = "OU=Accounts1";
        break;
    }
do
{
    System.out.println(searchBase);
    // Search for objects using the filter
        NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);

        //Loop through the search results
        while (answer.hasMoreElements())
        {
            SearchResult sr = (SearchResult)answer.next();
            Attributes attrs = sr.getAttributes();

            tempString = attrs.get("distinguishedName").toString();
            tempString = tempString.substring(tempString.indexOf(",")+4);
            tempString = tempString.substring(0, tempString.indexOf(",DC="));
            String[] reverseString = tempString.split(",OU=");
            List<String> reverseList = Arrays.asList(reverseString);  
            Collections.reverse(reverseList);
            tempString = "";

            for (String reverseString1: reverseString)
            {
                tempString = tempString + "\\" + reverseString1;
            }
            tempString = tempString.substring(1);
            location.add(tempString);

            String enableCheck = attrs.get("UserAccountControl").toString().replaceAll(".*: ", "");
            String isEnabled = isActive(enableCheck).toString();
            results1.add(attrs.get("Name").toString());
           // System.out.println(attrs.get("Name").toString());
            results2.add(attrs.get("samAccountName").toString());
            results4.add(isEnabled);

            if (attrs.get("mail") != null)
            {
                results3.add(attrs.get("mail").toString());
            }
            else
            {
                results3.add("");
            }

            Control[] controls = ctx.getResponseControls();

            if (controls != null) 
            {
              for (int i = 0; i < controls.length; i++) 
              {
                if (controls[i] instanceof PagedResultsResponseControl) 
                {
                  PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];
                  total = prrc.getResultSize();
                  if (total != 0) 
                  {
                    System.out.println("***************** END-OF-PAGE "
                        + "(total : " + total + ") *****************\n");
                  } 
                  else 
                  {
                    System.out.println("***************** END-OF-PAGE "
                        + "(total: unknown) ***************\n");
                  }
                  cookie = prrc.getCookie();
                }
              }
            } 
            else 
            {
              System.out.println("No controls were sent from the server");
            }
            // Re-activate paged results
            ctx.setRequestControls(new Control[] { new PagedResultsControl(
                pageSize, cookie, Control.CRITICAL) });
        } 
    } while (cookie != null);
    ctx.close();
}

catch (NamingException e)
{
    System.out.println("Search error: " + e);
    System.exit(-1);
} catch (IOException ex) 
{
    Logger.getLogger(ADData.class.getName()).log(Level.SEVERE, null, ex);
}
 Logger.getLogger(ADData.class.getName()).log(Level.SEVERE, null, ex);
}

I've changed a few things to hide some company data. 我做了一些更改以隐藏一些公司数据。 For every user it returns, it always outputs "No controls were sent from the server". 对于返回的每个用户,它始终输出“服务器未发送控件”。

Any idea of what could be causing it? 知道是什么原因引起的吗?

You've used Control.NONCRITICAL . 您已使用Control.NONCRITICAL From the documentation : 文档中

criticality - If true then the server must honor the control and return search results as indicated by pageSize or refuse to perform the search. criticality -如果为true,则服务器必须遵守该控件并按pageSize指示返回搜索结果,否则拒绝执行搜索。 If false, then the server need not honor the control. 如果为false,则服务器无需执行该控件。

So you're basically saying you're okay with it not honouring your page size. 因此,您基本上是说您可以接受它,而不尊重您的页面大小。 If you really, really need the page size to be honoured, used Control.CRITICAL - but be aware that that may cause the request to fail entirely. 如果确实需要兑现页面大小,请使用Control.CRITICAL但请注意,这可能会导致请求完全失败。

If you don't mind only receiving 1000 results at a time you need to use the pagination appropriately, setting the server-generated cookie to retrieve subsequent pages. 如果您不介意一次只接收1000个结果,则需要适当地使用分页,将服务器生成的cookie设置为检索后续页面。 It looks like you're trying to do that via the second ctx.setRequestControls call, but your code is somewhat broken: 看起来您正在尝试通过第二个ctx.setRequestControls调用来执行此ctx.setRequestControls ,但是您的代码有些破损:

  • Your while (cookie != null) loop isn't at the end of a do block, so I believe you've actually got code equivalent to: 您的while (cookie != null)循环不在do块的末尾,因此,我相信您实际上拥有的代码等效于:

    while (answer.hasMoreElements()) { ... } while (cookie != null) { ctx.close(); while(answer.hasMoreElements()){...} while(cookie!= null){ctx.close(); } }

  • You're not performing the search again. 您不会再次执行搜索。 I wouldn't personally expect setting the controls to automatically perform a new search. 我个人并不希望将控件设置为自动执行新搜索。 (I haven't used the LDAP API for ages, but I'd expect you to need to call ctx.search for it to have an effect.) (我已经很久没有使用LDAP API了,但是我希望您需要调用ctx.search才能起作用。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM