處理 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
類似於以下範例
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 介面是 LDAPv3 特有的,並且要求使用 `LdapContext` 而不是 `DirContext`。如果使用不是 `LdapContext` 的引數呼叫 `AbstractRequestControlDirContextProcessor` 子類別,則會擲回 `IllegalArgumentException`。 |
分頁搜尋結果
某些搜尋可能會傳回大量結果。當沒有簡單的方法可以篩選出較少量時,讓伺服器每次呼叫時僅傳回一定數量的結果會很方便。這稱為「分頁搜尋結果」。然後可以顯示結果的每個「頁面」,並提供指向上一頁和下一頁的連結。如果沒有此功能,用戶端必須手動將搜尋結果限制為頁面,或檢索整個結果,然後將其切成合適大小的頁面。前者會相當複雜,而後者會消耗不必要的記憶體量。
某些 LDAP 伺服器支援 `PagedResultsControl`,它要求 LDAP 伺服器以指定大小的頁面傳回搜尋操作的結果。使用者透過控制呼叫搜尋的速率來控制頁面傳回的速率。但是,您必須追蹤呼叫之間的 Cookie。伺服器使用此 Cookie 來追蹤上次使用分頁結果請求呼叫時的停止位置。
Spring LDAP 透過使用前幾節討論的 `LdapContext` 前處理和後處理概念,提供對分頁結果的支援。它透過使用 `PagedResultsDirContextProcessor` 類別來實現。`PagedResultsDirContextProcessor` 類別會建立具有請求頁面大小的 `PagedResultsControl`,並將其新增至 `LdapContext`。搜尋後,它會取得 `PagedResultsResponseControl` 並檢索分頁結果 Cookie,這對於在連續分頁結果請求之間保持上下文是必需的。
以下範例示範如何使用分頁搜尋結果功能
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` 來做到這一點,如前述範例所示。 |