处理DirContext

本节介绍如何处理DirContext,包括预处理和后处理。spring-doc.cadn.net.cn

习惯DirContext预处理和后处理

在某些情况下,您可能希望对DirContext搜索作之前和之后。用于此作的接口称为DirContextProcessor.以下列表显示了DirContextProcessor接口:spring-doc.cadn.net.cn

public interface DirContextProcessor {
   public void preProcess(DirContext ctx) throws NamingException;
   public void postProcess(DirContext ctx) throws NamingException;
}

LdapTemplate类有一个搜索方法,该方法采用DirContextProcessor如下:spring-doc.cadn.net.cn

public void search(SearchExecutor se, NameClassPairCallbackHandler handler,
   DirContextProcessor processor) throws DataAccessException;

在搜索作之前,preProcess方法在给定的DirContextProcessor实例。在运行搜索并生成NamingEnumeration已处理,postProcess方法被调用。这使您可以对DirContext用于搜索并检查DirContext执行搜索后。这可能非常有用(例如,在处理请求和响应控制时)。spring-doc.cadn.net.cn

当不需要自定义时,也可以使用以下方便的方法SearchExecutor:spring-doc.cadn.net.cn

public void search(Name base, String filter,
   SearchControls controls, NameClassPairCallbackHandler handler, DirContextProcessor processor)

public void search(String base, String filter,
   SearchControls controls, NameClassPairCallbackHandler handler, DirContextProcessor processor)

public void search(Name base, String filter,
   SearchControls controls, AttributesMapper mapper, DirContextProcessor processor)

public void search(String base, String filter,
   SearchControls controls, AttributesMapper mapper, DirContextProcessor processor)

public void search(Name base, String filter,
   SearchControls controls, ContextMapper mapper, DirContextProcessor processor)

public void search(String base, String filter,
   SearchControls controls, ContextMapper mapper, DirContextProcessor processor)

实现请求控制DirContextProcessor

LDAPv3 协议使用“控件”发送和接收附加数据,以影响预定义作的行为。简化请求控制的实现DirContextProcessor,Spring LDAP 提供AbstractRequestControlDirContextProcessor基类。此类处理从LdapContext,调用用于创建请求控件的模板方法,并将其添加到LdapContext.在子类中,您所要做的就是实现名为createRequestControlpostProcess方法,用于执行搜索后需要执行的任何作。以下列表显示了相关签名:spring-doc.cadn.net.cn

public abstract class AbstractRequestControlDirContextProcessor implements
      DirContextProcessor {

   public void preProcess(DirContext ctx) throws NamingException {
      ...
   }

   public abstract Control createRequestControl();
}

典型的DirContextProcessor类似于以下示例:spring-doc.cadn.net.cn

示例 1.请求控制DirContextProcessor实现
public class MyCoolRequestControl extends AbstractRequestControlDirContextProcessor {
   private static final boolean CRITICAL_CONTROL = true;
   private MyCoolCookie cookie;
   ...
   public MyCoolCookie getCookie() {
      return cookie;
   }

   public Control createRequestControl() {
      return new SomeCoolControl(cookie.getCookie(), CRITICAL_CONTROL);
   }

   public void postProcess(DirContext ctx) throws NamingException {
      LdapContext ldapContext = (LdapContext) ctx;
      Control[] responseControls = ldapContext.getResponseControls();

      for (int i = 0; i < responseControls.length; i++) {
         if (responseControls[i] instanceof SomeCoolResponseControl) {
            SomeCoolResponseControl control = (SomeCoolResponseControl) responseControls[i];
            this.cookie = new MyCoolCookie(control.getCookie());
         }
      }
   }
}
确保使用LdapContextSource当您使用控件时。这Control接口特定于 LDAPv3,并且要求LdapContext代替DirContext.如果AbstractRequestControlDirContextProcessor子类使用不是LdapContext,它会抛出一个IllegalArgumentException.

分页搜索结果

某些搜索可能会返回大量结果。当没有简单的方法来过滤掉较小的数量时,让服务器在每次调用时只返回一定数量的结果会很方便。这称为“分页搜索结果”。然后可以显示结果的每个“页面”,并带有指向下一页和上一页的链接。如果没有此功能,客户端必须手动将搜索结果限制为页面,或者检索整个结果,然后将其切成合适大小的页面。前者会相当复杂,后者会消耗不必要的内存量。spring-doc.cadn.net.cn

某些 LDAP 服务器支持PagedResultsControl,这请求 LDAP 服务器在指定大小的页面中返回搜索作的结果。用户通过控制调用搜索的速率来控制返回页面的速率。但是,您必须在调用之间跟踪 cookie。服务器使用此 cookie 来跟踪上次通过分页结果请求调用它时中断的位置。spring-doc.cadn.net.cn

Spring LDAP 通过使用对LdapContext,如前几节所述。它通过使用PagedResultsDirContextProcessor类。这PagedResultsDirContextProcessor类创建一个PagedResultsControl替换为请求的页面大小,并将其添加到LdapContext.搜索后,它会得到PagedResultsResponseControl并检索分页结果 cookie,这是在连续分页结果请求之间保持上下文所必需的。spring-doc.cadn.net.cn

以下示例演示如何使用分页搜索结果功能:spring-doc.cadn.net.cn

示例 2.使用PagedResultsDirContextProcessor
public List<String> getAllPersonNames() {
  final SearchControls searchControls = new SearchControls();
  searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

  final PagedResultsDirContextProcessor processor =
        new PagedResultsDirContextProcessor(PAGE_SIZE);

  return SingleContextSource.doWithSingleContext(
        contextSource, new LdapOperationsCallback<List<String>>() {

      @Override
      public List<String> doWithLdapOperations(LdapOperations operations) {
        List<String> result = new LinkedList<String>();

        do {
          List<String> oneResult = operations.search(
            "ou=People",
            "(&(objectclass=person))",
            searchControls,
            CN_ATTRIBUTES_MAPPER,
            processor);
          result.addAll(oneResult);
        } while(processor.hasMore());

        return result;
      }
  });
}
若要使分页结果 Cookie 继续有效,必须对每个分页结果调用使用相同的基础连接。您可以使用SingleContextSource,如前面的示例所示。