SpringLDAP-Reference(中文文档)(二)
第二章 基本操作
?在这个例子中,我们将使用AttributesMapper轻松的将person类型的对象属性返回。
?例2.1 AttributesMapper 返回一个单一属性
??packagecom.example.dao;
??publicclassPersonDaoImplimplementsPersonDao{
??privateLdapTemplateldapTemplate;
??publicvoidsetLdapTemplate(LdapTemplateldapTemplate){
??this.ldapTemplate=ldapTemplate;
??}
??publicListgetAllPersonNames(){
??returnldapTemplate.search(
??"","(objectclass=person)",
??newAttributesMapper(){
??publicObjectmapFromAttributes(Attributesattrs)
??throwsNamingException{
??returnattrs.get("cn").get();
??}
??});
??}
??}
?AttributesMapper的具体实现是从Attributes中得到想要的属性并返回,在内部,LdapTemplate遍历所有条目,给予AttributesMapper每个项(entry),并汇集结果放在一个集合中,然后向查询方法返回集合。
?
?例2.2 AttributesMapper 返回一个person对象
?
??packagecom.example.dao;
??publicclassPersonDaoImplimplementsPersonDao{
??privateLdapTemplateldapTemplate;
??...
??privateclassPersonAttributesMapperimplementsAttributesMapper{
??publicObjectmapFromAttributes(Attributesattrs)throwsNamingException{
??Personperson=newPerson();
??person.setFullName((String)attrs.get("cn").get());
??person.setLastName((String)attrs.get("sn").get());
??person.setDescription((String)attrs.get("description").get());
??returnperson;
??}
??}
??publicListgetAllPersons(){
??returnldapTemplate.search("","(objectclass=person)", newPersonAttributesMapper());
??}
??}
??
??如果你有一个DN直接标识一个条目,你可以直接找到它,而不需要去检索。这就是所谓的java ldap查找方式。下面示例展示了如何查找结果封装在一个person对象中
??
??例2.3 查找结果封装在一个person对象中
??
???packagecom.example.dao;
???publicclassPersonDaoImplimplementsPersonDao{
???privateLdapTemplateldapTemplate;
???...
???publicPersonfindPerson(Stringdn){
???return(Person)ldapTemplate.lookup(dn,newPersonAttributesMapper());
???}
???}
?????
??我们将根据指定的dn查找到我们想要的属性放在AttributesMapper中,在这种情况下,封装在person对象中
??
??2.2构建动态过滤器
??
??我们可以构建一个动态过滤器用于搜索中,使用的是org.springframework.ldap.filter包。比方说,我们希望下面的过滤器(&(objectclass=person)(sn=?)),其中的?替换成我们的参数值lastname,下面的代码告诉你我们是如何做到的:
??
??例2.4 构建动态过滤器
???packagecom.example.dao;
???publicclassPersonDaoImplimplementsPersonDao{
???privateLdapTemplateldapTemplate;
???...
???publicListgetPersonNamesByLastName(StringlastName){
???AndFilterfilter=newAndFilter();
???filter.and(newEqualsFilter("objectclass","person"));
???filter.and(newEqualsFilter("sn",lastName));
???returnldapTemplate.search(
???"", filter.encode(),
???newAttributesMapper(){
???publicObjectmapFromAttributes(Attributesattrs)
???throwsNamingException{
???returnattrs.get("cn").get();
???}
???});
???}
???}
???
??要使用通配符查询,可以用WhitespaceWildcardsFilter
??
??例2.5 构建通配符查询过滤器
???AndFilterfilter=newAndFilter();
???filter.and(newEqualsFilter("objectclass","person"));
???filter.and(newWhitespaceWildcardsFilter("cn",cn));
???
?注意:
??除了简化过滤器,过滤器本身也应该适当屏蔽一些不安全字符,这样是为了避免ldap注入,有些人可能利用这些字符注入ldap进行一些非法操作。
??
???
??2.3建立一个动态可识别的名称
??
??标准名称接口只是一个通用名称,它只是一个序列的基本组成部分,该名称接口还提供了关于序列的操作。例如 add和remove.LdapTemplate提供了一个name的接口实现,DistinguishedName,使用它可以轻松的建立一个可识别的名称。? 特别是考虑到复杂性和编码问题,这将有助于防止恶意代码注入到你的ldap中进行操作
??下面的例子说明了如何利用DistinguishedName来构建一个动态可识别名称
??
??例 2.6 建立一个动态可识别的名称
????packagecom.example.dao;
????importorg.springframework.ldap.core.support.DistinguishedName;
????importjavax.naming.Name;
????publicclassPersonDaoImplimplementsPersonDao{
????publicstaticfinalStringBASE_DN="dc=example,dc=com";
????...
????protectedNamebuildDn(Personp){
????DistinguishedNamedn=newDistinguishedName(BASE_DN);
????dn.add("c",p.getCountry());
????dn.add("ou",p.getCompany());
????dn.add("cn",p.getFullname());
????returndn;
????}
????}
????
??设想一个人有如下属性:
????
????country ??Sweden
????company ??SomeCompany
????fullname ??SomePerson
????
??以上的代码将会返回如下的可识别名称?
??cn=SomePerson,ou=SomeCompany,c=Sweden,dc=example,dc=com
??
??在Java5中有一个名称接口的实现Ldap Name,如果你使用Java5,你可以很好的使用LdapName,当然你也可以继续使用DistinguishedName?
??
?2.4绑定与反绑定
? 在JavaLdap中插入数据称为绑定,为了做到这一点,有一个准确可识别的名称,唯一的标识是插入条目所必须的,下面的代码展示了如何用LdapTemplate绑定一条数据
??
??例2.7 向条目上绑定属性?
???
??? packagecom.example.dao;
????publicclassPersonDaoImplimplementsPersonDao{
????privateLdapTemplateldapTemplate;
????...
????publicvoidcreate(Personp){
????Namedn=buildDn(p);
????ldapTemplate.bind(dn,null,buildAttributes(p));
????}
????privateAttributesbuildAttributes(Personp){
????Attributesattrs=newBasicAttributes();
????BasicAttributeocattr=newBasicAttribute("objectclass");
????ocattr.add("top");
????ocattr.add("person");
????attrs.put(ocattr);
????attrs.put("cn","SomePerson");
????attrs.put("sn","Person");
????returnattrs;
???}
???}
???
???
???属性的绑定的代码虽然比较枯燥和冗长,但是我们也有更简便的操作方式,这将是我们在第3章中所介绍的,用DirContextAdapter访问属性和操作
???
???2.4.2 反绑定数据
???
???删除数据在JavaLdap中我们称为反绑定,一个唯一的标识(DN)是识别条目所必须的,正如数据绑定一样。下面的示例演示了如何用LdapTemplate来反绑定数据
???
???例2.8 反绑定数据
???
????packagecom.example.dao;
????publicclassPersonDaoImplimplementsPersonDao{
????privateLdapTemplateldapTemplate;
????...
????publicvoiddelete(Personp){
????Namedn=buildDn(p);
????ldapTemplate.unbind(dn);
????}
????}
????
???2.5 修改
???在JavaLdap中修改数据有两种方法,用rebind和modifyAttrbutes
???
???2.5.1 用rebind修改
???
???用rebind去修改数据非常粗糙,它基本上就是拆散后再绑定,它看起来像这样
???
???例2.9 用rebind修改
???packagecom.example.dao;
???publicclassPersonDaoImplimplementsPersonDao{
???privateLdapTemplateldapTemplate;
???...
???publicvoidupdate(Personp){
???Namedn=buildDn(p);
???ldapTemplate.rebind(dn,null,buildAttributes(p));
???}
???}
???
???2.5.2 用ModifyAttrbutes修改
???
???如果只是修改属性,那么应该用ModifyAttrbutes,它用一个数组作为参数。
???
???例2.10 用ModifyAttrbutes修改
???
???packagecom.example.dao;
???publicclassPersonDaoImplimplementsPersonDao{
???privateLdapTemplateldapTemplate;
???...
???publicvoidupdateDescription(Personp){
???Namedn=buildDn(p);
???Attributeattr=newBasicAttribute("description",p.getDescription())
???ModificationItemitem=newModificationItem(DirContext.REPLACE_ATTRIBUTE,attr);
???ldapTemplate.modifyAttributes(dn,newModificationItem[]{item});
???}
???}
???
???构建属性和修改条目是一项工作量很大的工作,但是当你看到第三章 ,使用DirContextAdapter简便访问属性和操作,这一切将变得很简单
???
???2.6 示例应用
???
???最好的做法是查看Sping Ldap的示例包。包说明如下:
???
???1.spring-ldap-person-该示例展示了大部分功能
???2.spring-ldap-article-该示例展示了关于SpringLdap如何写入到java.net的article
???
???