|
该版本仍在开发中,尚未被视为稳定。对于最新稳定版本,请使用 Spring LDAP 4.0.0! |
处理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实例。 搜索结束后,结果命名枚举已经处理完毕,后处理调用了方法。这允许你对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,春季LDAP提供抽象请求控制DirContextProcessor基础类。该类处理从以下LdapContext调用一个模板方法来创建请求控制,并将其添加到LdapContext. 你只需要在子类中实现一个叫做的模板方法。createRequestControl以及后处理搜索后执行所需作的方法。以下列表展示了相关签名:
public abstract class AbstractRequestControlDirContextProcessor implements
DirContextProcessor {
public void preProcess(DirContext ctx) throws NamingException {
...
}
public abstract Control createRequestControl();
}
典型的DirContextProcessor类似于以下示例:
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当你使用控制装置时。 这控制接口是针对LDAPv3的专用,并且要求LdapContext用于代替DirContext. 如果抽象请求控制DirContextProcessor子类被调用的参数不是LdapContext,它抛出一个IllegalArgumentException. |
分页搜索结果
有些搜索可能会返回大量结果。当没有简单的方法过滤掉较小数量的结果时,方便让服务器每次调用只返回一定数量的结果。这被称为“分页搜索结果”。每个“页面”结果都可以显示,并链接到下一页和上一页。没有此功能,客户端要么手动将搜索结果限制为页面,要么检索整个结果后将其切割成合适大小的页面。前者相当复杂,后者会占用不必要的内存。
部分LDAP服务器支持PagedResultsControl,该请求LDAP服务器以指定大小的页面返回搜索作的结果。用户通过控制搜索调用的速率来控制页面返回的速度。不过,你必须在调用之间跟踪一个cookie。服务器使用该cookie来跟踪上一次被分页结果请求调用时的中断位置。
Spring LDAP通过使用预处理和后处理的概念,支持分页结果LdapContext,如前几节所述。它通过使用PagedResultsDirContextProcessor类。 这PagedResultsDirContextProcessor类创建PagedResultsControl带有请求的页面大小,并将其添加到LdapContext. 搜索完成后,它获得了PagedResultsResponseControl并检索分页结果 Cookie,该 cookie 用于保持连续分页结果请求之间的上下文。
以下示例展示了如何使用分页搜索结果功能:
PagedResultsDirContextProcessorpublic 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 继续有效,你必须为每个分页结果调用使用相同的底层连接。你可以通过使用单一语境源,如前例所示。 |