2023年6月21日发(作者:)

Spring ldap 中文文档(一)

第一章 介绍

1.1 概览

Spring-LDAP是一个java简单应用在LDAP开发的一个库,是采取类似Spring JDBC中的JdbcTemplate的原理建立的。它使得我们完全没必要考虑LdapContext的生成和关闭以及NamingEnumeration的循环。在Spring's DataAccessException基础上建立的Spring-LDAP提供一个更加全面且不用检查的异常处理机制。作为补充,Spring-LDAP也有了动态建立LDAP

filters和DNs(Distinguished Names)的类。

举个例子来说,如实现一个获取所有人员进入并返回存有他们名字的list的方法。用JDBC,我们得先生成一个connection,用statement执行一个query。然后我们要遍历resultset,找到我们需要的那个column,把它放入到list。类似地,用Java LDAP,我们先生成一个context,用search filter执行一个search。然后循环遍历resulting namingenumeration,找到需要的那个attribute,把它加入到list。

按传统的实现方法,用Java LDAP实现查找人员名称看起来应该是这样的:

package ;

public class TraditionalPersonDaoImpl implements PersonDao {

public List getAllPersonNames() {

Hashtable env = new Hashtable();

(L_CONTEXT_FACTORY, "xFactory");

(ER_URL, “ldap://localhost:389/dc=example,dc=com”);

DirContext ctx;

try {

ctx = new InitialDirContext(env);

} catch (NamingException e) {

throw new RuntimeException(e);

}

LinkedList list = new LinkedList();

NamingEnumeration results = null;

try {

SearchControls controls = new SearchControls();

rchScope(E_SCOPE);

results = ("", "(objectclass=person)", controls);

while (e()) {

SearchResult searchResult = (SearchResult) ();

Attributes attributes = ributes();

Attribute attr = ("cn");

String cn = (String) ();

(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 {

();

} catch (Exception e) {

// Never mind this.

}

}

if (ctx != null) {

try {

();

} catch (Exception e) {

// Never mind this.

}

}

}

return list;

}

}

通过spring的LDAP AttributesMapper,我们可以通过下面的代码实现完全一样的功能:

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public void setLdapTemplate(LdapTemplate ldapTemplate) {

mplate = ldapTemplate;

}

public List getAllPersonNames() {

return (

"", "(objectclass=person)",

new AttributesMapper() {

public Object mapFromAttributes(Attributes attrs)

throws NamingException {

return ("cn").get();

}

});

}

}

1.2 包

用Spring LDAP最小需要:

spring-ldap(spring-ldap包)

spring-core(用于框架内部的丰富的工具类)

spring-beans(方便操作java beans的接口和类)

spring-context(增加通过一致API为应用对象获取资源的能力)

spring-dao(使经常性的错误处理跟使用中的数据访问分开的异常处理机制)

commons-logging(简单的日志处理,内部使用)

在您的Spring context文件中设置需要的beans,然后把LdapTemplate注入到您的数据访问对象:

...

1.3 包架构

这部分包提供了Spring LDAP源代码的逻辑包架构的视图。每个包的依赖性清晰的标注。一个包依赖性是指需要依赖的包来编译这个包,但是运行的时候就不是必须的(依赖您自己要用的这个包)。例如,Spring LDAP 和Acegi Security一起用继承了ecurity这个包的使用。

1.3.1

这个ldap包包含了整个库的中心内容。这些内容包括AttributesMapper,ContextSource,和NameClassPairCallbackHandler.这个也包括中心类LdapTemplate.

依赖:spring-core,spring-beans,spring-context,spring-dao,commons-logging(TBD).

1.3.2 t

support包有支持中心接口实现类和DirContextAdapter abstraction。

依赖:ldap

1.3.3 tication

support authentication包有用于acegi security的认证资源接口的实现。

依赖:ldap,acegi-security(optional)

1.3.4

support filter包有Filter 抽象接口和几个它的实现类。

依赖:commons-lang

1.4 支持

Spring LDAP 1.0.3支持Spring 1.2.7以上版本

第二章 基本操作

2.1 使用 AttributesMapper

在下面的例子中我们将用AttributesMapper很容易地得到所有person对象的名字的结果列表。

Example 2.1. AttributesMapper 返回一个简单属性

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public void setLdapTemplate(LdapTemplate ldapTemplate) {

mplate = ldapTemplate;

}

public List getAllPersonNames() {

return (

"", "(objectclass=person)",

new AttributesMapper() {

public Object mapFromAttributes(Attributes attrs)

throws NamingException {

return ("cn").get();

}

});

} }

上面粗题字部分是AttributesMapper的实现,它通过属性名称获取到了需要的属性值,然后返回结果。中心代码是LdapTemplate枚举了所有发现的数据入口,通过调用对每个入口特定的AttributesMapper收集得到结果,然后把结果放入list。list通过search方法返回结果值。

如果你有标志一个入口的distinguished name(dn),你就可以直接获取这个入口,而不用去搜索它。这个在Java LDAP就叫着一个lookup。下面的例子就展示了一个lookup怎样得到person对象的结果集的。

Example 2.3. A lookup resulting in a Person object

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public Person findPerson(String dn) {

return (Person) (dn, new PersonAttributesMapper());

}

}

这里将遍历特别的dn,把发现的属性集发送到已经提供的AttributesMapper,然后得到person对象的结果集。

2.2 建立动态的Filters

我们可以使用包里的类建立动态filters实现在搜索中的应用。我们来做下面所需要的filter:(&(objectclass=person)(sn=?)这里我们要用参数lastName的值去取代?的值。下面展示如何实现这个filter:

Example 2.4. Building a search filter dynamically

package ; ?/P>

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public List getPersonNamesByLastName(String lastName) {

AndFilter filter = new AndFilter();

(new EqualsFilter("objectclass", "person"));

(new EqualsFilter("sn", lastName));

return (

"", (),

new AttributesMapper() {

public Object mapFromAttributes(Attributes attrs)

throws NamingException {

return ("cn").get();

}

});

}

}

为了完成一个通配符搜索,可能要用到WhitespaceWildcardsFilter:

Example 2.5. Building a wildcard search filter

AndFilter filter = new AndFilter();

(new EqualsFilter("objectclass", "person"));

(new WhitespaceWildcardsFilter("cn", cn));

2.3 建立动态dn

标准的Name interface代表了一个普通的名称,它基本上是一个一定规则的组件序列。在那个序列的Name interface也提供了基本的一些操作,比如添加和删除。LdapTemplate提供了Name interface的实现:DistinguishedName。用这个类将大大的简化了建立distinguished

names(dn),特别考虑到有时关于escapings和encodings的复杂规则。下面的例子阐述了DistinguishedName是怎样被用来构造一个dn的。

Example 2.6. Building a distinguished name dynamically

package ;

import guishedName;

import ;

public class PersonDaoImpl implements PersonDao {

public static final String BASE_DN = "dc=example,dc=com";

...

protected Name buildDn(Person p) {

DistinguishedName dn = new DistinguishedName(BASE_DN);

("c", ntry());

("ou", pany());

("cn", lname());

return dn;

}

}

假如一个person有以下属性:

country

Sweden

company

Some Company

fullname

Some Person

上面的代码将产生下面dn的结果:

cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com

在java5中,有个Name interface的实现:LdapName。

如果你是在用java5,你可能需要用到LdapName。当然,如果你希望用DistinguishedName,那你可以还用DistinguishedName。

2.4 绑定和解绑定

2.4.1 数据绑定

在Java LDAP中插入数据叫做绑定。为了做到绑定,一个唯一标志新entry的dn是必须的。下面的例子展示了数据是如何通过LdapTemplate绑定的:

Example 2.7. Binding data using Attributes

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void create(Person p) {

Name dn = buildDn(p);

(dn, null, buildAttributes(p));

}

private Attributes buildAttributes(Person p) { Attributes attrs = new BasicAttributes();

BasicAttribute ocattr = new BasicAttribute("objectclass");

("top");

("person");

(ocattr);

("cn", "Some Person");

("sn", "Person");

return attrs;

}

}

Attributes的建立是在减少和冗长时候起了足够的作用。当然他对进一步的地简化绑定操作提供了可能,这个将在第三章描述。

2.4.2 解绑定数据

在Java LDAP中删除数据就叫着解绑定数据,入口(entry)是需要dn来唯一标志,就像绑定操作一样。下面的例子展示了使用LdapTemplate怎样来解绑定数据:

Example 2.8. Unbinding data

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void delete(Person p) {

Name dn = buildDn(p);

(dn);

} }

2.5 修改

在Java LDAP,数据修改可以有两种方式:使用rebind或者modifyAttributes。

2.5.1 使用rebind修改

使用rebind修改数据是一种比较鲁莽的方式。它基本上就是跟在绑定后面的解绑定。它看起来像这样:

Example 2.9. Modifying using rebind

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void update(Person p) {

Name dn = buildDn(p);

(dn, null, buildAttributes(p));

}

}

2.5.2 使用modifyAttributes修改

如果需要修改的属性应该被取代,有一个获取一组修正的方法叫modifyAttributes。

Example 2.10. Modifying using modifyAttributes

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void updateDescription(Person p) {

Name dn = buildDn(p);

Attribute attr = new BasicAttribute("description", cription())

ModificationItem item = new ModificationItem(E_ATTRIBUTE, attr);

Attributes(dn, new ModificationItem[] {item});

}

}

2023年6月21日发(作者:)

Spring ldap 中文文档(一)

第一章 介绍

1.1 概览

Spring-LDAP是一个java简单应用在LDAP开发的一个库,是采取类似Spring JDBC中的JdbcTemplate的原理建立的。它使得我们完全没必要考虑LdapContext的生成和关闭以及NamingEnumeration的循环。在Spring's DataAccessException基础上建立的Spring-LDAP提供一个更加全面且不用检查的异常处理机制。作为补充,Spring-LDAP也有了动态建立LDAP

filters和DNs(Distinguished Names)的类。

举个例子来说,如实现一个获取所有人员进入并返回存有他们名字的list的方法。用JDBC,我们得先生成一个connection,用statement执行一个query。然后我们要遍历resultset,找到我们需要的那个column,把它放入到list。类似地,用Java LDAP,我们先生成一个context,用search filter执行一个search。然后循环遍历resulting namingenumeration,找到需要的那个attribute,把它加入到list。

按传统的实现方法,用Java LDAP实现查找人员名称看起来应该是这样的:

package ;

public class TraditionalPersonDaoImpl implements PersonDao {

public List getAllPersonNames() {

Hashtable env = new Hashtable();

(L_CONTEXT_FACTORY, "xFactory");

(ER_URL, “ldap://localhost:389/dc=example,dc=com”);

DirContext ctx;

try {

ctx = new InitialDirContext(env);

} catch (NamingException e) {

throw new RuntimeException(e);

}

LinkedList list = new LinkedList();

NamingEnumeration results = null;

try {

SearchControls controls = new SearchControls();

rchScope(E_SCOPE);

results = ("", "(objectclass=person)", controls);

while (e()) {

SearchResult searchResult = (SearchResult) ();

Attributes attributes = ributes();

Attribute attr = ("cn");

String cn = (String) ();

(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 {

();

} catch (Exception e) {

// Never mind this.

}

}

if (ctx != null) {

try {

();

} catch (Exception e) {

// Never mind this.

}

}

}

return list;

}

}

通过spring的LDAP AttributesMapper,我们可以通过下面的代码实现完全一样的功能:

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public void setLdapTemplate(LdapTemplate ldapTemplate) {

mplate = ldapTemplate;

}

public List getAllPersonNames() {

return (

"", "(objectclass=person)",

new AttributesMapper() {

public Object mapFromAttributes(Attributes attrs)

throws NamingException {

return ("cn").get();

}

});

}

}

1.2 包

用Spring LDAP最小需要:

spring-ldap(spring-ldap包)

spring-core(用于框架内部的丰富的工具类)

spring-beans(方便操作java beans的接口和类)

spring-context(增加通过一致API为应用对象获取资源的能力)

spring-dao(使经常性的错误处理跟使用中的数据访问分开的异常处理机制)

commons-logging(简单的日志处理,内部使用)

在您的Spring context文件中设置需要的beans,然后把LdapTemplate注入到您的数据访问对象:

...

1.3 包架构

这部分包提供了Spring LDAP源代码的逻辑包架构的视图。每个包的依赖性清晰的标注。一个包依赖性是指需要依赖的包来编译这个包,但是运行的时候就不是必须的(依赖您自己要用的这个包)。例如,Spring LDAP 和Acegi Security一起用继承了ecurity这个包的使用。

1.3.1

这个ldap包包含了整个库的中心内容。这些内容包括AttributesMapper,ContextSource,和NameClassPairCallbackHandler.这个也包括中心类LdapTemplate.

依赖:spring-core,spring-beans,spring-context,spring-dao,commons-logging(TBD).

1.3.2 t

support包有支持中心接口实现类和DirContextAdapter abstraction。

依赖:ldap

1.3.3 tication

support authentication包有用于acegi security的认证资源接口的实现。

依赖:ldap,acegi-security(optional)

1.3.4

support filter包有Filter 抽象接口和几个它的实现类。

依赖:commons-lang

1.4 支持

Spring LDAP 1.0.3支持Spring 1.2.7以上版本

第二章 基本操作

2.1 使用 AttributesMapper

在下面的例子中我们将用AttributesMapper很容易地得到所有person对象的名字的结果列表。

Example 2.1. AttributesMapper 返回一个简单属性

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public void setLdapTemplate(LdapTemplate ldapTemplate) {

mplate = ldapTemplate;

}

public List getAllPersonNames() {

return (

"", "(objectclass=person)",

new AttributesMapper() {

public Object mapFromAttributes(Attributes attrs)

throws NamingException {

return ("cn").get();

}

});

} }

上面粗题字部分是AttributesMapper的实现,它通过属性名称获取到了需要的属性值,然后返回结果。中心代码是LdapTemplate枚举了所有发现的数据入口,通过调用对每个入口特定的AttributesMapper收集得到结果,然后把结果放入list。list通过search方法返回结果值。

如果你有标志一个入口的distinguished name(dn),你就可以直接获取这个入口,而不用去搜索它。这个在Java LDAP就叫着一个lookup。下面的例子就展示了一个lookup怎样得到person对象的结果集的。

Example 2.3. A lookup resulting in a Person object

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public Person findPerson(String dn) {

return (Person) (dn, new PersonAttributesMapper());

}

}

这里将遍历特别的dn,把发现的属性集发送到已经提供的AttributesMapper,然后得到person对象的结果集。

2.2 建立动态的Filters

我们可以使用包里的类建立动态filters实现在搜索中的应用。我们来做下面所需要的filter:(&(objectclass=person)(sn=?)这里我们要用参数lastName的值去取代?的值。下面展示如何实现这个filter:

Example 2.4. Building a search filter dynamically

package ; ?/P>

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

public List getPersonNamesByLastName(String lastName) {

AndFilter filter = new AndFilter();

(new EqualsFilter("objectclass", "person"));

(new EqualsFilter("sn", lastName));

return (

"", (),

new AttributesMapper() {

public Object mapFromAttributes(Attributes attrs)

throws NamingException {

return ("cn").get();

}

});

}

}

为了完成一个通配符搜索,可能要用到WhitespaceWildcardsFilter:

Example 2.5. Building a wildcard search filter

AndFilter filter = new AndFilter();

(new EqualsFilter("objectclass", "person"));

(new WhitespaceWildcardsFilter("cn", cn));

2.3 建立动态dn

标准的Name interface代表了一个普通的名称,它基本上是一个一定规则的组件序列。在那个序列的Name interface也提供了基本的一些操作,比如添加和删除。LdapTemplate提供了Name interface的实现:DistinguishedName。用这个类将大大的简化了建立distinguished

names(dn),特别考虑到有时关于escapings和encodings的复杂规则。下面的例子阐述了DistinguishedName是怎样被用来构造一个dn的。

Example 2.6. Building a distinguished name dynamically

package ;

import guishedName;

import ;

public class PersonDaoImpl implements PersonDao {

public static final String BASE_DN = "dc=example,dc=com";

...

protected Name buildDn(Person p) {

DistinguishedName dn = new DistinguishedName(BASE_DN);

("c", ntry());

("ou", pany());

("cn", lname());

return dn;

}

}

假如一个person有以下属性:

country

Sweden

company

Some Company

fullname

Some Person

上面的代码将产生下面dn的结果:

cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com

在java5中,有个Name interface的实现:LdapName。

如果你是在用java5,你可能需要用到LdapName。当然,如果你希望用DistinguishedName,那你可以还用DistinguishedName。

2.4 绑定和解绑定

2.4.1 数据绑定

在Java LDAP中插入数据叫做绑定。为了做到绑定,一个唯一标志新entry的dn是必须的。下面的例子展示了数据是如何通过LdapTemplate绑定的:

Example 2.7. Binding data using Attributes

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void create(Person p) {

Name dn = buildDn(p);

(dn, null, buildAttributes(p));

}

private Attributes buildAttributes(Person p) { Attributes attrs = new BasicAttributes();

BasicAttribute ocattr = new BasicAttribute("objectclass");

("top");

("person");

(ocattr);

("cn", "Some Person");

("sn", "Person");

return attrs;

}

}

Attributes的建立是在减少和冗长时候起了足够的作用。当然他对进一步的地简化绑定操作提供了可能,这个将在第三章描述。

2.4.2 解绑定数据

在Java LDAP中删除数据就叫着解绑定数据,入口(entry)是需要dn来唯一标志,就像绑定操作一样。下面的例子展示了使用LdapTemplate怎样来解绑定数据:

Example 2.8. Unbinding data

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void delete(Person p) {

Name dn = buildDn(p);

(dn);

} }

2.5 修改

在Java LDAP,数据修改可以有两种方式:使用rebind或者modifyAttributes。

2.5.1 使用rebind修改

使用rebind修改数据是一种比较鲁莽的方式。它基本上就是跟在绑定后面的解绑定。它看起来像这样:

Example 2.9. Modifying using rebind

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void update(Person p) {

Name dn = buildDn(p);

(dn, null, buildAttributes(p));

}

}

2.5.2 使用modifyAttributes修改

如果需要修改的属性应该被取代,有一个获取一组修正的方法叫modifyAttributes。

Example 2.10. Modifying using modifyAttributes

package ;

public class PersonDaoImpl implements PersonDao {

private LdapTemplate ldapTemplate;

...

public void updateDescription(Person p) {

Name dn = buildDn(p);

Attribute attr = new BasicAttribute("description", cription())

ModificationItem item = new ModificationItem(E_ATTRIBUTE, attr);

Attributes(dn, new ModificationItem[] {item});

}

}