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

我正在使用此站点的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”。

虽然几乎可以肯定服务器正在强制执行1000个条目的大小限制,但是有可能通过在多个部分中发出请求来解决这个问题。

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

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

使用标准java实现分页LDAP查询非常简单,方法是使用向LdapContext添加PagedResultsControl ,而不使用根据Neil上面的答案使用第三方API。

 Hashtable env = new Hashtable(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(); 

从这里复制的示例。

我像@PeterK一样解决了,但有一些修改

  public List listUsers() { LOG.info("listUsers() inicio"); List users = new ArrayList(); Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CTX); env.put(Context.PROVIDER_URL, 'ldap://192.168.10.10:389'); env.put(Context.SECURITY_AUTHENTICATION, CONNECTION_TYPE); env.put(Context.SECURITY_PRINCIPAL, USER_ADMIN_PASSWORD); env.put(Context.SECURITY_CREDENTIALS, USER_ADMIN); try { LdapContext ctx = new InitialLdapContext(env, null); // Activate paged results int pageSize = 1000; byte[] cookie = null; ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.NONCRITICAL) }); int total; do { /* perform the search */ SearchControls sc = new SearchControls(); sc.setSearchScope(SearchControls.SUBTREE_SCOPE); String filtro = "(&(sAMAccountName=*)&(objectClass=user))"; NamingEnumeration results = ctx.search(getBaseDn(ctx), filtro, sc); /* for each entry */ while (results.hasMoreElements()) { SearchResult result = (SearchResult) results.nextElement(); Attributes attributes = result.getAttributes(); //convert to MyUser class MyUser user = toUser(attributes); users.add(user); } // 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(); } catch (NamingException e) { System.err.println("PagedSearch failed."); e.printStackTrace(); } catch (IOException ie) { System.err.println("PagedSearch failed."); ie.printStackTrace(); } catch (Exception ie) { System.err.println("PagedSearch failed."); ie.printStackTrace(); } LOG.info("listUsers() size = " + (users.size())); LOG.info("listUsers() fim"); return users; } private MyUser toUser(Attributes attributes) throws NamingException { if (attributes != null) { String fullName = attributes.get("distinguishedName") != null ? attributes.get("distinguishedName").get().toString() : null; String mail = attributes.get("mail") != null ? attributes.get("mail").get().toString() : null; String userName = attributes.get("cn") != null ? attributes.get("cn").get().toString() : null; String userPrincipalName = attributes.get("userPrincipalName") != null ? attributes.get("userPrincipalName").get().toString() : null; if (userPrincipalName != null) { String[] user = userPrincipalName.split("@"); if (user != null && user.length > 0) { userName = user[0]; } } MyUser user = new MyUser(); user.setFullName(fullName); user.setEmail(mail); user.setName(userName); user.setUserPrincipalName(userPrincipalName); user.setRoles(getRolesUser(attributes)); return user; } return null; } 

LDAP客户端设置的“客户端请求”大小限制为2000.此客户端请求的限制不能覆盖服务器配置中设置的限制。 无论客户端请求的大小限制是什么,服务器的大小限制都会覆盖它。 请与目录服务器管理员联系,并要求增加大小限制。