2011-09-30 98 views
3

请看下面的测试课程。我正在尝试使用Spring LDAP模板进行LDAP搜索。我可以使用SearchWithoutTemplate()方法中显示的DirContext来搜索并生成与搜索条件相对应的条目列表,而无需使用Spring LDAP模板。但是当我使用LdapTemplate时,我最终会得到如下所示的NPE。我相信我一定会错过一些东西。有人可以帮忙吗?春季LDAP模板用法

import java.util.Hashtable; 
import javax.naming.Context; 
import javax.naming.NamingEnumeration; 
import javax.naming.NamingException; 
import javax.naming.directory.Attribute; 
import javax.naming.directory.Attributes; 
import javax.naming.directory.DirContext; 
import javax.naming.directory.InitialDirContext; 
import javax.naming.directory.SearchControls; 
import javax.naming.directory.SearchResult; 
import javax.naming.ldap.LdapName; 
import org.springframework.ldap.core.AttributesMapper; 
import org.springframework.ldap.core.LdapTemplate; 
import org.springframework.ldap.core.support.DefaultDirObjectFactory; 
import org.springframework.ldap.core.support.LdapContextSource; 

public class LDAPSearchTest { 
    //bind params 
    static String url="ldap://<IP>:<PORT>"; 
    static String userName="cn=Directory Manager"; 
    static String password="password123"; 
    static String bindDN="dc=XXX,dc=com"; 

    //search params 
    static String base = "ou=StandardUser,ou=XXXCustomers,ou=People,dc=XXX,dc=com"; 
    static String filter = "(objectClass=*)"; 
    static String[] attributeFilter = { "cn", "uid" }; 
    static SearchControls sc = new SearchControls(); 

    public static void main(String[] args) throws Exception { 
     // sc.setSearchScope(SearchControls.SUBTREE_SCOPE); 
     sc.setReturningAttributes(attributeFilter); 
     searchWithTemplate(); //NPE 
     //searchWithoutTemplate(); //works fine 
    } 

    public static void searchWithTemplate() throws Exception { 
     DefaultDirObjectFactory factory = new DefaultDirObjectFactory(); 
     LdapContextSource cs = new LdapContextSource(); 
     cs.setUrl(url); 
     cs.setUserDn(userName); 
     cs.setPassword(password); 
     cs.setBase(bindDN); 
     cs.setDirObjectFactory(factory.getClass()); 
     LdapTemplate template = new LdapTemplate(cs); 
     template.afterPropertiesSet(); 
     System.out.println((template.search(new LdapName(base), filter, sc, 
       new AttributesMapper() { 
        public Object mapFromAttributes(Attributes attrs) 
          throws NamingException { 
         System.out.println(attrs); 
         return attrs.get("uid").get(); 
        } 
       }))); 
    } 

    public static void searchWithoutTemplate() throws NamingException{ 
     Hashtable env = new Hashtable(11); 
     env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); 
     env.put(Context.PROVIDER_URL, url); 
     //env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
     env.put(Context.SECURITY_PRINCIPAL, userName); 
     env.put(Context.SECURITY_CREDENTIALS, password); 
     DirContext dctx = new InitialDirContext(env); 
     NamingEnumeration results = dctx.search(base, filter, sc); 
     while (results.hasMore()) { 
      SearchResult sr = (SearchResult) results.next(); 
      Attributes attrs = sr.getAttributes(); 
      System.out.println(attrs); 
      Attribute attr = attrs.get("uid"); 
     } 
     dctx.close(); 
    } 
} 

的例外是:

Exception in thread "main" java.lang.NullPointerException 
    at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:125) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:287) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:237) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:588) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:546) 
    at LDAPSearchTest.searchWithTemplate(LDAPSearchTest.java:47) 
at LDAPSearchTest.main(LDAPSearchTest.java:33) 

我使用Spring 2.5.6和Spring 1.3.0 LDAP

回答

3

快速扫描显示,它是AbstractContextSourceauthenticationSource字段是罪魁祸首。该文件包括关于afterPropertiesSet()方法如下评论:

/** 
* Checks that all necessary data is set and that there is no compatibility 
* issues, after which the instance is initialized. Note that you need to 
* call this method explicitly after setting all desired properties if using 
* the class outside of a Spring Context. 
*/ 
public void afterPropertiesSet() throws Exception { 
    ... 
} 

该方法然后继续,如果您没有提供一个创建一个合适的authenticationSource。 如上测试代码是最肯定一个Spring上下文中运行,并且您还没有明确设置的authenticationSource,我想你需要如下修改代码:

... 
cs.setDirObjectFactory(factory.getClass()); 

// Allow Spring to configure the Context Source: 
cs.afterPropertiesSet(); 

LdapTemplate template = new LdapTemplate(cs);