2012-07-03 6 views
11

Sto utilizzando l'SDK LDAP da questo sito: https://www.unboundid.com/products/ldap-sdk/. Vorrei effettuare un'operazione di ricerca che restituisca molte voci.LDAP: come restituire più di 1000 risultati (java)

In base al sito delle Domande frequenti (https://www.unboundid.com/products/ldap-sdk/docs/ldapsdk-faq.php#search), devo utilizzare un'implementazione SearchResultListener.

ecco quello che ho fatto:

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()); 

} 

Il problema è che "searchEntryReturned" restituisce un massimo di 1000 risultati. Anche se ho impostato il limite di dimensione su "2000".

risposta

8

Sebbene sia quasi certamente il caso che il server imponga il limite di 1000 voci, ci sono potenzialmente modi per aggirarlo emettendo la richiesta in più parti.

Se il server supporta l'utilizzo del semplice controllo dei risultati di paging (come definito in RFC 2696 e supportato nell'SDAP LDAP come da https://docs.ldap.com/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/controls/SimplePagedResultsControl.html), è possibile utilizzarlo per scorrere i risultati in "pagine" contenenti uno specifico numero di entrate.

In alternativa, è possibile utilizzare il controllo di richiesta di visualizzazione di lista virtuale (VLV) (https://www.unboundid.com/products/ldap-sdk/docs/javadoc/index.html?com/unboundid/ldap/sdk/controls/VirtualListViewRequestControl.html), ma probabilmente lo raccomanderei solo se il server non supporta il semplice controllo dei risultati di pagina perché il controllo di richiesta VLV richiede anche che il i risultati devono essere ordinati, e ciò probabilmente richiede una configurazione speciale nel server o qualche elaborazione piuttosto costosa per poter servire la richiesta.

+0

ha funzionato (semplice controllo risultati paging)! Grazie mille ! – stage

5

Il client LDAP imposta un limite di dimensione "client-richiesto" di 2000. Questo limite richiesto dal client non può ignorare i limiti impostati nella configurazione del server. Indipendentemente dal limite di dimensioni richiesto dal client, il limite di dimensioni del server lo sostituisce. Contattare l'amministratore del server di directory e chiedere che venga aumentato il limite di dimensioni.

8

È piuttosto semplice implementare una query LDAP cercapersone utilizzando java standard, utilizzando l'aggiunta di PagedResultsControl a LdapContext, senza utilizzare un'API di terze parti come da risposta di Neil sopra.

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(); 

Esempio copiato da here.

4

ho risolto come @PeterK, ma con alcune modifiche

public List<MyUser> listUsers() { 
    LOG.info("listUsers() inicio"); 
    List<MyUser> users = new ArrayList<MyUser>(); 

    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; 
} 
+0

PeterK non vedrà mai il tuo messaggio come hai fatto – Drew

+0

Come si fa? ... –

+0

inserire un commento sotto la sua risposta. Ricorda: sotto la tua risposta le seguenti persone vengono allertate quando pubblichi un commento sotto la tua risposta ... (1) l'op penso ma non mi trattenere, (2) un altro commentatore come me se quella persona è l'unica persona con un thread di commento come in nessun altro sta commentando, (3) qualcuno tu @theirName che è già sotto la tua risposta in un commento o l'Op – Drew