2011-09-30 92 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);