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());
         }
      }
   }
}
コントロールを使用する場合は、必ず LdapContextSource を使用してください。Control (標準 Javadoc) (英語) インターフェースは LDAPv3 に固有であり、DirContext の代わりに LdapContext を使用する必要があります。AbstractRequestControlDirContextProcessor サブクラスが LdapContext ではない引数で呼び出されると、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 を使用してこれを行うことができます。