簡介
本節對 Spring LDAP 進行了相對快速的介紹。它包含以下內容:
概覽
Spring LDAP 旨在簡化 Java 中的 LDAP 程式設計。該庫提供的一些特性包括:
-
對 LDAP 程式設計進行類似
JdbcTemplate
風格的模板簡化。 -
類似 JPA 或 Hibernate 的基於註解的物件與目錄對映。
-
Spring Data repository 支援,包括對 QueryDSL 的支援。
-
用於簡化構建 LDAP 查詢和辨別名(Distinguished Names)的工具。
-
正確的 LDAP 連線池。
-
客戶端 LDAP 補償事務支援。
傳統 Java LDAP 與 LdapClient
的比較
考慮一個方法,它應該在某個儲存中搜索所有人員並以列表形式返回他們的姓名。使用 JDBC,我們將建立一個連線並使用一個語句執行一個查詢。然後,我們將遍歷結果集並檢索我們想要的列,將其新增到列表中。
使用 JNDI 操作 LDAP 資料庫時,我們將建立一個上下文並使用一個搜尋過濾器執行一次搜尋。然後,我們將遍歷生成的命名列舉,檢索我們想要的屬性,並將其新增到列表中。
在 Java LDAP 中實現此人員姓名搜尋方法的傳統方式如下所示。請注意標記為粗體的程式碼 - 這是實際執行與方法業務目的相關的任務的程式碼。其餘的是樣板程式碼(plumbing)。
public class TraditionalPersonRepoImpl implements PersonRepo {
public List<String> getAllPersonNames() {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://:389/dc=example,dc=com");
DirContext ctx;
try {
ctx = new InitialDirContext(env);
} catch (NamingException e) {
throw new RuntimeException(e);
}
List<String> list = new LinkedList<String>();
NamingEnumeration results = null;
try {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
results = ctx.search("", "(objectclass=person)", controls);
while (results.hasMore()) {
SearchResult searchResult = (SearchResult) results.next();
Attributes attributes = searchResult.getAttributes();
Attribute attr = attributes.get("cn");
String cn = attr.get().toString();
list.add(cn);
}
} catch (NameNotFoundException e) {
// The base context was not found.
// Just clean up and exit.
} catch (NamingException e) {
throw new RuntimeException(e);
} finally {
if (results != null) {
try {
results.close();
} catch (Exception e) {
// Never mind this.
}
}
if (ctx != null) {
try {
ctx.close();
} catch (Exception e) {
// Never mind this.
}
}
}
return list;
}
}
透過使用 Spring LDAP 的 AttributesMapper
和 LdapClient
類,我們可以使用以下程式碼獲得完全相同的功能:
import static org.springframework.ldap.query.LdapQueryBuilder.query;
public class PersonRepoImpl implements PersonRepo {
private LdapClient ldapClient;
public void setLdapClient(LdapClient ldapClient) {
this.ldapClient = ldapClient;
}
public List<String> getAllPersonNames() {
return ldapClient.search().query(
query().where("objectclass").is("person")
).toObject((Attributes attrs) ->
attrs.get("cn").get().toString();
);
}
}
與傳統示例相比,樣板程式碼量顯著減少。LdapClient
搜尋方法確保建立了 DirContext
例項,執行搜尋,使用給定的 AttributesMapper
將屬性對映為字串,在內部列表中收集這些字串,最後返回該列表。它還確保 NamingEnumeration
和 DirContext
被正確關閉,並處理可能發生的任何異常。
當然,作為 Spring Framework 的一個子專案,我們使用 Spring 來配置我們的應用程式,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ldap="http://www.springframework.org/schema/ldap"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/ldap https://www.springframework.org/schema/ldap/spring-ldap.xsd">
<ldap:context-source
url="ldap://:389"
base="dc=example,dc=com"
username="cn=Manager"
password="secret" />
<bean id="ldapClient" class="org.springframework.ldap.core.LdapClient" factory-method="create">
<constructor-arg ref="contextSource" />
</bean>
<bean id="personRepo" class="com.example.repo.PersonRepoImpl">
<property name="ldapClient" ref="ldapClient" />
</bean>
</beans>
要使用自定義 XML 名稱空間配置 Spring LDAP 元件,您需要在 XML 宣告中包含對該名稱空間的引用,如前面的示例所示。 |
2.0 版本的新特性
雖然 Spring LDAP 2.0 版本對 API 進行了相當重要的現代化改進,但我們已盡最大努力確保向後相容性。使用 Spring LDAP 1.3.x 的程式碼,除少數例外,在使用 2.0 庫時無需修改即可編譯和執行。
例外情況是少數已移至新包的類,這是為了實現一些重要的重構。這些被移動的類通常不是預期公共 API 的一部分,遷移過程應該是平滑的。如果在升級後找不到 Spring LDAP 類,您應該在 IDE 中組織匯入。
不過,您應該會遇到一些棄用警告,並且還有許多其他的 API 改進。為了充分利用 2.0 版本,建議您放棄棄用的類和方法,遷移到新的、改進的 API 工具。
以下列表簡要描述了 Spring LDAP 2.0 中最重要的變化:
-
Spring LDAP 現在需要 Java 6。Spring 2.0 及更高版本仍然受支援。
-
核心 API 已更新,支援 Java 5+ 的特性,例如泛型和可變引數。因此,整個
spring-ldap-tiger
模組已被棄用,我們鼓勵您遷移到使用核心 Spring LDAP 類。核心介面的引數化會在現有程式碼上引起大量編譯警告,我們鼓勵您採取適當措施消除這些警告。 -
ODM(物件-目錄對映)功能已移至核心模組,
LdapOperations
和LdapTemplate
中新增了一些方法,使用這種自動轉換來處理帶有 ODM 註解的類。有關更多資訊,請參閱物件-目錄對映 (ODM)。 -
現在(終於)提供了自定義 XML 名稱空間,以簡化 Spring LDAP 的配置。有關更多資訊,請參閱[配置]。
-
Spring LDAP 現在提供對 Spring Data Repository 和 QueryDSL 的支援。有關更多資訊,請參閱Spring LDAP 儲存庫。
-
在
DirContextAdapter
和 ODM 中,現在正確處理了作為屬性值的Name
例項,特別是關於辨別名相等性。有關更多資訊,請參閱DirContextAdapter
和屬性值作為辨別名 以及 ODM 和屬性值作為辨別名。 -
DistinguishedName
和相關類已被棄用,取而代之的是標準的 JavaLdapName
。有關在使用LdapName
物件時該庫如何提供幫助的資訊,請參閱動態構建辨別名。 -
添加了 Fluent LDAP 查詢構建支援。這使得在 Spring LDAP 中處理 LDAP 搜尋時程式設計體驗更加愉快。有關 LDAP 查詢構建器支援的更多資訊,請參閱構建 LDAP 查詢 和 高階 LDAP 查詢。
-
LdapTemplate
中舊的authenticate
方法已被棄用,取而代之的是幾個新的authenticate
方法,這些方法使用LdapQuery
物件,並在認證失敗時丟擲異常,使使用者更容易查明認證嘗試失敗的原因。 -
已對示例進行了完善和更新,以便利用 2.0 中的特性。我們付出了相當大的努力來提供一個有用的LDAP 使用者管理應用程式示例。
打包概覽
至少,使用 Spring LDAP 需要以下依賴項:
-
spring-ldap-core
:Spring LDAP 庫 -
spring-core
:框架內部使用的各種工具類 -
spring-beans
:用於操作 Java bean 的介面和類 -
slf4j
:一個簡單的日誌門面,內部使用
除了必需的依賴項外,某些功能還需要以下可選依賴項:
-
spring-data-ldap
:用於儲存庫支援等的基礎設施 -
spring-context
:如果您的應用程式使用 Spring Application Context 進行裝配,則需要此依賴項。spring-context
增加了應用程式物件使用一致 API 獲取資源的能力。如果您計劃使用BaseLdapPathBeanPostProcessor
,則絕對需要它。 -
spring-tx
:如果您計劃使用客戶端補償事務支援,則需要此依賴項。 -
spring-jdbc
:如果您計劃使用客戶端補償事務支援,則需要此依賴項。 -
commons-pool
:如果您計劃使用連線池功能,則需要此依賴項。 -
spring-batch
:如果您計劃將 LDIF 解析功能與 Spring Batch 一起使用,則需要此依賴項。
spring-data-ldap 會傳遞性地新增 spring-repository.xsd ,而 spring-ldap.xsd 使用它。因此,即使不使用 Spring Data 的特性集,Spring LDAP 的 XML 配置支援也需要此依賴項。 |
入門
示例提供了一些關於如何在常見用例中使用 Spring LDAP 的有用示例。
支援
如果您有問題,請在 Stack Overflow 上使用 spring-ldap
標籤提問。專案網頁是 spring.io/spring-ldap/。
致謝
感謝 Structure101 提供了開源許可,這對於檢查專案結構非常有用。