處理 DirContext

本節介紹如何處理 DirContext,包括預處理和後處理。

自定義 DirContext 預處理和後處理

在某些情況下,您可能希望在搜尋操作之前和之後對 DirContext 執行操作。用於此的介面稱為 DirContextProcessor。以下列表顯示了 DirContextProcessor 介面

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

LdapTemplate 類有一個接受 DirContextProcessor 的搜尋方法,如下所示

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

在搜尋操作之前,將呼叫給定 DirContextProcessor 例項的 preProcess 方法。在搜尋執行並處理了生成的 NamingEnumeration 之後,將呼叫 postProcess 方法。這允許您對用於搜尋的 DirContext 執行操作,並在執行搜尋後檢查 DirContext。這非常有用(例如,在處理請求和響應控制元件時)。

當您不需要自定義 SearchExecutor 時,您還可以使用以下便捷方法

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。您在子類中需要做的就是實現名為 createRequestControl 的模板方法和 postProcess 方法,以執行搜尋後需要做的任何事情。以下列表顯示了相關的簽名

public abstract class AbstractRequestControlDirContextProcessor implements
      DirContextProcessor {

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

   public abstract Control createRequestControl();
}

典型的 DirContextProcessor 類似於以下示例

示例 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());
         }
      }
   }
}
使用控制元件時,請務必使用 LdapContextSourceControl 介面特定於 LDAPv3,並且要求使用 LdapContext 而不是 DirContext。如果使用非 LdapContext 引數呼叫 AbstractRequestControlDirContextProcessor 子類,它將丟擲 IllegalArgumentException

分頁搜尋結果

某些搜尋可能會返回大量結果。當沒有簡單的方法過濾出較少數量的結果時,方便的是讓伺服器每次呼叫只返回一定數量的結果。這被稱為“分頁搜尋結果”。結果的每個“頁面”都可以顯示,並帶有指向下一頁和上一頁的連結。如果沒有此功能,客戶端必須手動將搜尋結果限制為頁面,或者檢索整個結果,然後將其分割成適當大小的頁面。前者會相當複雜,後者會消耗不必要的記憶體。

一些 LDAP 伺服器支援 PagedResultsControl,它要求 LDAP 伺服器以指定大小的頁面返回搜尋操作的結果。使用者透過控制搜尋的呼叫速率來控制頁面返回的速率。但是,您必須在呼叫之間跟蹤一個 cookie。伺服器使用此 cookie 來跟蹤上次使用分頁結果請求呼叫時停止的位置。

Spring LDAP 透過使用 LdapContext 的預處理和後處理概念來支援分頁結果,如前幾節所述。它透過使用 PagedResultsDirContextProcessor 類來實現。PagedResultsDirContextProcessor 類使用請求的頁面大小建立一個 PagedResultsControl 並將其新增到 LdapContext。搜尋後,它獲取 PagedResultsResponseControl 並檢索分頁結果 cookie,這對於在連續的分頁結果請求之間保持上下文是必需的。

以下示例展示瞭如何使用分頁搜尋結果功能

示例 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 來實現,如前一個示例所示。
© . This site is unofficial and not affiliated with VMware.