LDAP:如何返回超过 1000 个结果 (java)

2022-09-02 19:32:01

我正在从这个网站使用LDAP SDK:https://www.unboundid.com/products/ldap-sdk/。我想做一个返回大量条目的搜索操作。

根据FAQ的网站,( https://www.unboundid.com/products/ldap-sdk/docs/ldapsdk-faq.php#search)我必须使用SearchResultListener实现。

所以这是我所做的:

 public class UpdateThread extends Thread implements SearchResultListener {
 ...
 // create request
 final SearchRequest request = new SearchRequest(this, instance.getBaseDN(),SearchScope.SUB, filter);
 // Setting size limit of results.
 request.setSizeLimit(2000);

 ...

 // Get every result one by one.
 @Override
public void searchEntryReturned(SearchResultEntry arg0) {
    System.out.println("entry "+arg0.getDN());

}

问题是“searchEntryReturned”最多返回1000个结果。即使我将大小限制设置为“2000”。


答案 1

使用标准java实现分页LDAP查询非常简单,通过使用向添加a,而无需按照Neil上面的答案使用第三方API。PagedResultsControlLdapContext

Hashtable<String, Object> env = new Hashtable<String, Object>(11);
env
    .put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");

/* Specify host and port to use for directory service */
env.put(Context.PROVIDER_URL,
    "ldap://localhost:389/ou=People,o=JNDITutorial");

try {
  LdapContext ctx = new InitialLdapContext(env, null);

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

  do {
    /* perform the search */
    NamingEnumeration results = ctx.search("", "(objectclass=*)",
        new SearchControls());

    /* for each entry print out name + all attrs and values */
    while (results != null && results.hasMore()) {
      SearchResult entry = (SearchResult) results.next();
      System.out.println(entry.getName());
    }

    // Examine the paged results control response
    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();

示例从此处复制。


答案 2

尽管几乎可以肯定,服务器正在强制实施 1000 个条目的大小限制,但有一些可能的方法可以通过在多个部分中发出请求来解决此问题。

如果服务器支持使用简单的分页结果控件(在 RFC 2696 中定义,并且根据 https://docs.ldap.com/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/controls/SimplePagedResultsControl.html 在 LDAP SDK 中受支持),则可以使用它来循环访问包含指定数目条目的“页面”中的结果。

或者,可以使用虚拟列表视图(VLV)请求控件(https://www.unboundid.com/products/ldap-sdk/docs/javadoc/index.html?com/unboundid/ldap/sdk/controls/VirtualListViewRequestControl.html),但我可能只建议在服务器不支持简单的分页结果控件的情况下使用,因为VLV请求控件还需要对结果进行排序,并且可能需要在服务器中进行特殊配置或一些非常昂贵的配置。 处理以便能够为请求提供服务。


推荐