添加缺失的重载 API 方法

本节介绍如何添加自己的重载 API 方法来实现新功能。

实现自定义搜索方法

LdapTemplate 包含了 DirContext 中最常见操作的几个重载版本。然而,我们并没有为每一个方法签名都提供替代方案,主要是因为方法签名实在太多了。不过,我们提供了一种方法,让你可以调用任何你想要的 DirContext 方法,同时仍然能获得 LdapTemplate 带来的便利。

假设你想调用以下 DirContext 方法

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

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

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

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

示例 1:使用 SearchExecutorAttributesMapper 的自定义搜索方法
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,以下示例展示了如何操作

示例 2:使用 SearchExecutorContextMapper 的自定义搜索方法
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)

实现其他自定义 Context 方法

与自定义 search 方法类似,你实际上可以使用 ContextExecutor 调用 DirContext 中的任何方法,如下所示

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

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

Object lookupLink(Name name)

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

示例 3:使用 ContextExecutor 的自定义 DirContext 方法
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() 方法执行读写操作。