2012-07-03 2 views
11

이 사이트의 LDAP SDK는 https://www.unboundid.com/products/ldap-sdk/입니다. 많은 항목을 반환하는 검색 작업을하고 싶습니다.LDAP : 1000 개가 넘는 결과를 반환하는 방법 (Java)

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"으로 설정하더라도

답변

8

서버가 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 요청 컨트롤을 사용하려면 서버에서 간단한 페이지 결과 컨트롤을 지원하지 않으면 서버를 지원하지 않는 것이 좋습니다. 결과가 정렬되고 요청에 서비스 할 수 있도록 서버에서 특수한 구성이나 꽤 비싼 처리가 필요합니다.

+0

으로는 (단순 페이지 된 결과 제어)했다! 정말 고마워 ! – stage

5

LDAP 클라이언트가 "클라이언트가 요청한"크기 제한 2000을 설정하고 있습니다.이 클라이언트가 요청한 제한은 서버 구성에서 설정된 제한을 무시할 수 없습니다. 클라이언트가 요청한 크기 제한이 무엇이든 관계없이 서버의 크기 제한이이를 초과합니다. 디렉토리 서버 관리자에게 문의하여 크기 제한을 늘리십시오.

8

위의 Neil의 대답에 따라 타사 API를 사용하지 않고 LdapContextPagedResultsControl을 추가하여 표준 Java를 사용하여 페이징 된 LDAP 쿼리를 구현하는 것은 매우 간단합니다.

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

예제는 here에서 복사됩니다.

4

나는 @PeterK처럼 해결하지만, 일부 수정

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는 당신이 그랬던 것처럼 당신의 메시지를 결코 볼 수 없습니다 – Drew

+0

어떻게합니까? ... –

+0

당신은 그의 대답 아래에 코멘트를 입력 할 것입니다. 기억하십시오 : 귀하의 답변 아래에 귀하의 답변 아래에 의견을 게시 할 때 다음 사람들이 경고를받습니다 ... (1) 동의하지만 생각하지 말고, (2) 그 사람이 유일한 사람이라면 나 같은 다른 의견 작성자 아무도 코멘트가없는 사람이 댓글을 달았습니다. (3) 댓글 또는 Op에 이미 답을 남긴 사람이 있습니다. – Drew

관련 문제