`
xrb2008
  • 浏览: 169602 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

SpringLDAP-Reference(中文文档)(三)

阅读更多

第三章 通过DirContextAdapter进行简单的属性访问及操作

3.1介绍

 一个鲜为人知的可能被低估的Java Ldap Api DirContextAdapter 可以去创建一个context,它被很少用的原因是实现它需要创建一个Dircontext实例,Spring Ldap弥补了它的不足:一个默认的DirContext实现称作DirContextAdapter,与之相对应的DirObjectFactory的实现称作DefaultDirObjectFactory,同时使用DefaultDirObjectFactory,DirContextAdapter将变得非常实用。
 
 3.2 使用ContextMapper搜索和查找
 
  通常DefaultDirObjectFactory是注册在ContextSource中,这意味着每当在Ldap树中发现Context,它的属性和唯一Dn将用于构建一个DirContextAdapter,这将使我们用
  ContextMapper去转换查询到的值而不是AttributeMapper。
    
  例 3.1 使用ContextMapper查询  
  packagecom.example.dao;
  publicclassPersonDaoImplimplementsPersonDao{
  ...
  privatestaticclassPersonContextMapperimplementsContextMapper{
  publicObjectmapFromContext(Objectctx){
  DirContextAdaptercontext=(DirContextAdapter)ctx;
  Personp=newPerson();
  p.setFullName(context.getStringAttribute("cn"));
  p.setLastName(context.getStringAttribute("sn"));
  p.setDescription(context.getStringAttribute("description"));
  returnp;
  }
  }
  publicPersonfindByPrimaryKey(
  Stringname,Stringcompany,Stringcountry){
  Namedn=buildDn(name,company,country);
  returnldapTemplate.lookup(dn, newPersonContextMapper());
  }
  }
  
  上面的代码展示了我们可以直接通过名字查找属性,而不需要Attributes 和 BasicAttribute ,这在我们面对多个属性值的时候非常有用。取得多属性通常我们要使用
  NamingEnumeration循环,从attrbutes得到值。但是DirContextAdapter可以帮助我们做到这一点,使用getStringAttributes()或者getObjectAttributes()方法
   
   例3.2 :使用getStringAttributes()取得属性的多个值
   privatestaticclassPersonContextMapperimplementsContextMapper{
   publicObjectmapFromContext(Objectctx){
   DirContextAdaptercontext=(DirContextAdapter)ctx;
   Personp=newPerson();
   p.setFullName(context.getStringAttribute("cn"));
   p.setLastName(context.getStringAttribute("sn"));
   p.setDescription(context.getStringAttribute("description"));
   //TheroleNamespropertyofPersonisanStringarray
   p.setRoleNames(context.getStringAttributes("roleNames"));
   returnp;
   }
   }
   
   3.2.1.The AbstractContextMapper
   
   SpringLDAP提供了一个ContextMapper的抽象类AbstractContextMapper,它将提供构建好的DirContexOperations参数,上面的PersonContextMapper可以重写如下:
   
   例3.3 使用AbstractContextMapper
   privatestaticclassPersonContextMapper extendsAbstractContextMapper {
   publicObject doMapFromContext(DirContextOperationsctx){
   Personp=newPerson();
   p.setFullName(context.getStringAttribute("cn"));
   p.setLastName(context.getStringAttribute("sn"));
   p.setDescription(context.getStringAttribute("description"));
   returnp;
   }
   }0
   
   3.3使用DirContextAdapter绑定和修改
   
   相对于提取数据,DirContextAdapter在绑定和修改数据时隐藏属性细节方面的效率更高
   
   3.3.1 绑定
   这是一个改进的创建方法,请对照2.4.1的实现方式
  
   packagecom.example.dao;
   publicclassPersonDaoImplimplementsPersonDao{
   ...
   publicvoidcreate(Personp){
   Namedn=buildDn(p);
   DirContextAdaptercontext=newDirContextAdapter(dn);
   context.setAttributeValues("objectclass",newString[]{"top","pers
   context.setAttributeValue("cn",p.getFullname());
   context.setAttributeValue("sn",p.getLastname());
   context.setAttributeValue("description",p.getDescription());
   ldapTemplate.bind(context);
   }
   }
   
   注意,这里DirContextAdapter作为第二个参数绑定(?),没有第三个参数,没有使用任何attributes
   另外注意的是setAttributeValues()方法参数ObjectClass有两个值,如同取属性值一样麻烦,构建多值属性是繁琐和冗长的,你可以使用setAttributeValues()一次性完成它。
   3.3.2 修改
   
   反绑定代码和例3.4 几乎相同,“Bindingusing DirContextAdapter” 除了需要重新绑定。正如我们看到的2.5.2 。更合理的方法是用ModificationItem包含你想要做的操作,这将由你来决定在LdapTree中要操作的数据,而且DirContextAdapter可以帮助你,DirContextAdapter可以更好保持修改的属性,下面示例展示了这一功能
   
   例3.5 使用DirContextAdapter修改
   packagecom.example.dao;
   publicclassPersonDaoImplimplementsPersonDao{
   ...
   publicvoidupdate(Personp){
   Namedn=buildDn(p);
   DirContextOperationscontext=ldapTemplate.lookupContext(dn);
   context.setAttributeValues("objectclass",newString[]{"top","person"});
   context.setAttributeValue("cn",p.getFullname());
   context.setAttributeValue("sn",p.getLastname());
   context.setAttributeValue("description",p.getDescription());
   ldapTemplate.modifyAttributes(context);
   }
   }
   
   当ldapTemplate.lookup()操作没有返回值时将返回一个DirContextAdapter实例,虽然返回了一个对象,但更好的方法是自动强制返回一个DirContextOperations
   (DirContextAdapter的实现方法)
   
   细心的读者可能看来我们的create 和update方法中存在着重复,如果在同一类中,可以提取为一个单独的方法
   
   例3.6 用DirContextAdapter绑定和修改
   
   packagecom.example.dao;
   publicclassPersonDaoImplimplementsPersonDao{
   privateLdapTemplateldapTemplate;
   ...
   publicvoidcreate(Personp){
   Namedn=buildDn(p);
   DirContextAdaptercontext=newDirContextAdapter(dn);
   mapToContext(p,context);
   ldapTemplate.bind(context);
   }
   publicvoidupdate(Personp){
   Namedn=buildDn(p);
   DirContextOperationscontext=ldapTemplate.lookupContext(dn);
   mapToContext(person,context);
   ldapTemplate.modifyAttributes(context);
   }
   protectedvoidmapToContext(Personp,DirContextOperationscontext){
   context.setAttributeValues("objectclass",newString[]{"top","person"});
   context.setAttributeValue("cn",p.getFullName());
   context.setAttributeValue("sn",p.getLastName());
   context.setAttributeValue("description",p.getDescription());
   }
   }
   
   3.4 一个完整的PersonDao类
   
   例3.7
   
   packagecom.example.dao;
importjava.util.List;
importjavax.naming.Name;
importjavax.naming.NamingException;
importjavax.naming.directory.Attributes;
importorg.springframework.ldap.core.AttributesMapper;
importorg.springframework.ldap.core.ContextMapper;
importorg.springframework.ldap.core.LdapTemplate;
importorg.springframework.ldap.core.DirContextAdapter;
importorg.springframework.ldap.core.support.DistinguishedName;
importorg.springframework.ldap.filter.AndFilter;
importorg.springframework.ldap.filter.EqualsFilter;
importorg.springframework.ldap.filter.WhitespaceWildcardsFilter;
publicclassPersonDaoImplimplementsPersonDao{
privateLdapTemplateldapTemplate;
publicvoidsetLdapTemplate(LdapTemplateldapTemplate){
this.ldapTemplate=ldapTemplate;
}
publicvoidcreate(Personperson){
DirContextAdaptercontext=newDirContextAdapter(buildDn(person));
mapToContext(person,context);
ldapTemplate.bind(context);
}
publicvoidupdate(Personperson){
Namedn=buildDn(person);
DirContextOperationscontext=ldapTemplate.lookupContext(dn);
mapToContext(person,context);
ldapTemplate.modifyAttributes(context);
}
publicvoiddelete(Personperson){
ldapTemplate.unbind(buildDn(person));
}
publicPersonfindByPrimaryKey(Stringname,Stringcompany,Stringcountry){
Namedn=buildDn(name,company,country);
return(Person)ldapTemplate.lookup(dn,getContextMapper());
}
publicListfindByName(Stringname){
AndFilterfilter=newAndFilter();
filter.and(newEqualsFilter("objectclass","person")).and(newWhitespaceWildcardsFilter("cn",name));
returnldapTemplate.search(DistinguishedName.EMPTY_PATH,filter.encode(),getContextMapper());
}
publicListfindAll(){
EqualsFilterfilter=newEqualsFilter("objectclass","person");
returnldapTemplate.search(DistinguishedName.EMPTY_PATH,filter.encode(),getContextMapper());
}
protectedContextMappergetContextMapper(){
returnnewPersonContextMapper();
}
protectedNamebuildDn(Personperson){
returnbuildDn(person.getFullname(),person.getCompany(),person.getCountry());
}
protectedNamebuildDn(Stringfullname,Stringcompany,Stringcountry){
DistinguishedNamedn=newDistinguishedName();
dn.add("c",country);
dn.add("ou",company);
dn.add("cn",fullname);
returndn;
}
protectedvoidmapToContext(Personperson,DirContextOperationscontext){
context.setAttributeValues("objectclass",newString[]{"top","person"});
context.setAttributeValue("cn",person.getFullName());
context.setAttributeValue("sn",person.getLastName());
context.setAttributeValue("description",person.getDescription());
}
privatestaticclassPersonContextMapperextendsAbstractContextMapper{
publicObjectdoMapFromContext(DirContextOperationscontext){
Personperson=newPerson();
person.setFullName(context.getStringAttribute("cn"));
person.setLastName(context.getStringAttribute("sn"));
person.setDescription(context.getStringAttribute("description"));
returnperson;
}
}
}

注意

在很多种情况下,唯一的DN用做构建对象时的重要属性,例如上面的代码中一个人的country,company 和fullname都用到DN,这就意味着你要在LdapTree中找到Entry,然后才能用rename()去更新属性值。如果你要保持不变的话,可以禁止用户修改属性或者rename()它

 

2
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics