Adding Missing Overloaded API Methods

本节涵盖了如何添加自己的重载 API 方法以实现新功能。

This section covers how to add your own overloaded API methods to implement new functionality.

Implementing Custom Search Methods

LdapTemplate 包含 DirContext 中最常见操作的多个重载版本。但是,我们并未为每种方法签名提供替代方法,主要是因为这些方法实在太多了。不过,我们提供了一种方法,您可以调用任何 DirContext 方法,同时仍然可以获得 LdapTemplate 提供的好处。

LdapTemplate contains several overloaded versions of the most common operations in DirContext. However, we have not provided an alternative for each and every method signature, mostly because there are so many of them. We have, however, provided a means to call whichever DirContext method you want and still get the benefits that LdapTemplate provides.

假设您想调用以下 DirContext 方法:

Suppose you want to call the following DirContext method:

NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls ctls)

LdapTemplate 中没有对应的重载方法。解决方法是使用自定义 SearchExecutor 实现,如下所示:

There is no corresponding overloaded method in LdapTemplate. The way to solve this is to use a custom SearchExecutor implementation, as follows:

public interface SearchExecutor {
   public NamingEnumeration executeSearch(DirContext ctx) throws NamingException;
}

在您的自定义执行器中,您可以访问 DirContext 对象,可以使用它来调用所需的方法。然后,您可以提供一个处理程序,负责映射属性和收集结果。例如,您可以使用 CollectingNameClassPairCallbackHandler 的可用实现之一,它会在内部列表中收集映射后的结果。为了实际执行搜索,您需要调用 LdapTemplate 中的 search 方法,该方法将执行器和处理程序作为参数。最后,您需要返回处理程序收集的任何内容。以下示例演示了如何执行所有这些操作:

In your custom executor, you have access to a DirContext object, which you can use to call the method you want. You can then provide a handler that is responsible for mapping attributes and collecting the results. You can, for example, use one of the available implementations of CollectingNameClassPairCallbackHandler, which collects the mapped results in an internal list. In order to actually perform the search, you need to call the search method in LdapTemplate that takes an executor and a handler as arguments. Finally, you need to return whatever your handler has collected. The following example shows how to do all of that:

Example 1. A custom search method using SearchExecutor and AttributesMapper
public class PersonRepoImpl implements PersonRepo {
   ...
   public List search(final Name base, final String filter, final String[] params,
         final SearchControls ctls) {
      *SearchExecutor executor = new SearchExecutor() {
         public NamingEnumeration executeSearch(DirContext ctx) {
            return ctx.search(base, filter, params, ctls);
         }
      };*

      CollectingNameClassPairCallbackHandler handler =
         new AttributesMapperCallbackHandler(new PersonAttributesMapper());

      ldapTemplate.search(*executor*, handler);
      return handler.getList();
   }
}

如果你更喜欢使用 ContextMapper 而不是 AttributesMapper,以下示例展示了它的样子:

If you prefer the ContextMapper to the AttributesMapper, the following example shows what it would look like:

Example 2. A custom search method using SearchExecutor and ContextMapper
public class PersonRepoImpl implements PersonRepo {
   ...
   public List search(final Name base, final String filter, final String[] params,
         final SearchControls ctls) {
      SearchExecutor executor = new SearchExecutor() {
         public NamingEnumeration executeSearch(DirContext ctx) {
            return ctx.search(base, filter, params, ctls);
         }
      };

      CollectingNameClassPairCallbackHandler handler =
         *new ContextMapperCallbackHandler(new PersonContextMapper()*);

      ldapTemplate.search(executor, handler);
      return handler.getList();
   }
}

当您使用 ContextMapperCallbackHandler 时,您必须确保在您的 SearchControls 实例上调用 setReturningObjFlag(true)

When you use the ContextMapperCallbackHandler, you must make sure that you have called setReturningObjFlag(true) on your SearchControls instance.

Implementing Other Custom Context Methods

与自定义`search` 方法相同,你实际上可以通过使用 ContextExecutor 调用 DirContext 的任何方法,如下所示:

In the same manner as for custom search methods, you can actually call any method in DirContext by using a ContextExecutor, as follows:

public interface ContextExecutor {
   public Object executeWithContext(DirContext ctx) throws NamingException;
}

在实现自定义 ContextExecutor 时,你可以选择使用 executeReadOnly()executeReadWrite() 方法。假设你希望调用以下方法:

When implementing a custom ContextExecutor, you can choose between using the executeReadOnly() or the executeReadWrite() method. Suppose you want to call the following method:

Object lookupLink(Name name)

此方法在 DirContext 中可用,但在 LdapTemplate 中没有匹配的方法。这是一个查找方法,所以它应该是只读的。我们可以按照以下方式来实现它:

The method is available in DirContext, but there is no matching method in LdapTemplate. It is a lookup method, so it should be read-only. We can implement it as follows:

Example 3. A custom DirContext method using ContextExecutor
public class PersonRepoImpl implements PersonRepo {
   ...
   public Object lookupLink(final Name name) {
      ContextExecutor executor = new ContextExecutor() {
         public Object executeWithContext(DirContext ctx) {
            return ctx.lookupLink(name);
         }
      };

      return ldapTemplate.executeReadOnly(executor);
   }
}

以相同的方式,你可以通过使用 executeReadWrite() 方法来执行读写操作。

In the same manner, you can perform a read-write operation by using the executeReadWrite() method.