Basic Operations
Search and Lookup Using AttributesMapper
In this example we will use an AttributesMapper
to easily build a List of all common names of all person objects.
AttributesMapper that returns a single attribute
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public List getAllPersonNames() {
return ldapTemplate.search(
"", "(objectclass=person)",
new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
throws NamingException {
return attrs.get("cn").get();
}
});
}
}
The inline implementation of AttributesMapper
just gets the desired attribute value from the
Attributes and returns it. Internally,
LdapTemplate iterates over all entries found, calling
the given AttributesMapper for each entry, and collects
the results in a list. The list is then returned by the
search method.
Note that the AttributesMapper implementation
could easily be modified to return a full Person
object:
AttributesMapper that returns a Person object
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
private class PersonAttributesMapper implements AttributesMapper {
public Object mapFromAttributes(Attributes attrs) throws NamingException {
Person person = new Person();
person.setFullName((String)attrs.get("cn").get());
person.setLastName((String)attrs.get("sn").get());
person.setDescription((String)attrs.get("description").get());
return person;
}
}
public List getAllPersons() {
return ldapTemplate.search("", "(objectclass=person)", new PersonAttributesMapper());
}
}
If you have the distinguished name (dn) that
identifies an entry, you can retrieve the entry directly, without
searching for it. This is called a lookup in Java
LDAP. The following example shows how a lookup results in a Person
object:
A lookup resulting in a Person object
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public Person findPerson(String dn) {
return (Person) ldapTemplate.lookup(dn, new PersonAttributesMapper());
}
}
This will look up the specified dn and pass the
found attributes to the supplied AttributesMapper, in
this case resulting in a Person object.
Building Dynamic Filters
We can build dynamic filters to use in searches, using the classes
from the org.springframework.ldap.filter
package. Let's say that we want the following filter:
(&(objectclass=person)(sn=?)), where we want the
? to be replaced with the value of the parameter
lastName. This is how we do it using the filter support
classes:
Building a search filter dynamically
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public List getPersonNamesByLastName(String lastName) {
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person"));
filter.and(new EqualsFilter("sn", lastName));
return ldapTemplate.search(
"", filter.encode(),
new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
throws NamingException {
return attrs.get("cn").get();
}
});
}
}
To perform a wildcard search, it's possible to use the
WhitespaceWildcardsFilter:
Building a wildcard search filter
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person"));
filter.and(new WhitespaceWildcardsFilter("cn", cn));
In addition to simplifying building of complex search filters,
the Filter classes also provide proper escaping
of any unsafe characters. This prevents "ldap injection",
where a user might use such characters to inject unwanted operations
into your LDAP operations.
Building Dynamic Distinguished Names
The standard Name
interface represents a generic name, which is basically an ordered
sequence of components. The Name interface also
provides operations on that sequence; e.g., add or
remove. LdapTemplate provides an implementation of the
Name interface: DistinguishedName.
Using this class will greatly simplify building distinguished names,
especially considering the sometimes complex rules regarding escapings and
encodings. As with the Filter classes this helps preventing
potentially malicious data being injected into your LDAP operations.
The following example illustrates how
DistinguishedName can be used to dynamically construct
a distinguished name:
Building a distinguished name dynamically
package com.example.dao;
import org.springframework.ldap.core.support.DistinguishedName;
import javax.naming.Name;
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);
dn.add("c", p.getCountry());
dn.add("ou", p.getCompany());
dn.add("cn", p.getFullname());
return dn;
}
}
Assuming that a Person has the following attributes:
country
Sweden
company
Some Company
fullname
Some Person
The code above would then result in the following distinguished
name:
cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com
In Java 5, there is an implementation of the Name interface: LdapName.
If you are in the Java 5 world, you might as well use
LdapName. However, you may still use
DistinguishedName if you so wish.
Binding and Unbinding
Binding Data
Inserting data in Java LDAP is called binding. In order to do
that, a distinguished name that uniquely identifies the new entry is
required. The following example shows how data is bound using
LdapTemplate:
Binding data using Attributes
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void create(Person p) {
Name dn = buildDn(p);
ldapTemplate.bind(dn, null, buildAttributes(p));
}
private Attributes buildAttributes(Person p) {
Attributes attrs = new BasicAttributes();
BasicAttribute ocattr = new BasicAttribute("objectclass");
ocattr.add("top");
ocattr.add("person");
attrs.put(ocattr);
attrs.put("cn", "Some Person");
attrs.put("sn", "Person");
return attrs;
}
}
The Attributes building is--while dull and verbose--sufficient for
many purposes. It is, however, possible to simplify the binding
operation further, which will be described in .
Unbinding Data
Removing data in Java LDAP is called unbinding. A distinguished
name (dn) is required to identify the entry, just as in the binding
operation. The following example shows how data is unbound using
LdapTemplate:
Unbinding data
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void delete(Person p) {
Name dn = buildDn(p);
ldapTemplate.unbind(dn);
}
}
Modifying
In Java LDAP, data can be modified in two ways: either using
rebind or
modifyAttributes.
Modifying using rebind
A rebind is a very crude way to modify data.
It's basically an unbind followed by a
bind. It looks like this:
Modifying using rebind
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void update(Person p) {
Name dn = buildDn(p);
ldapTemplate.rebind(dn, null, buildAttributes(p));
}
}
Modifying using modifyAttributes
If only the modified attributes should be replaced, there is a
method called modifyAttributes that takes an array of
modifications:
Modifying using modifyAttributes
package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void updateDescription(Person p) {
Name dn = buildDn(p);
Attribute attr = new BasicAttribute("description", p.getDescription())
ModificationItem item = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
ldapTemplate.modifyAttributes(dn, new ModificationItem[] {item});
}
}
Building Attributes and
ModificationItem arrays is a lot of work, but as you
will see in , the update operations
can be simplified.
Sample applications
It is recommended that you review the Spring LDAP sample
applications included in the release distribution for best-practice
illustrations of the features of this library. A description of each
sample is provided below:
spring-ldap-person - the sample demonstrating most
features.
spring-ldap-article - the sample application that was written
to accompany a java.net
article about Spring LDAP.