使用ldapsdk.jar连接到Ldap服务器ipnalet过程如下:
1. 获取连接池.
Ldapsdk 提供了连接池类ConnectionPool,可以通过构造函数来构造连接池.显然,这个动作应该被封装到一个singleton中.
ConnectionPool = new ConnectionPool(MIN_CONN_SIZE, MAX_CONN_SIZE, HOST, PORT)
参数的意思很显然,第一个定义了连接池的最小连接数,第二个参数定义了连接池的最大连接数,第三个参数指定将要连接到的Ldap主机地址,第四个参数是端口.
2. 获取连接和关闭连接.
可以通过ConnectionPool提供的getConnection()方法获取连接,但是最后要调用close(LDAPConnection)方法来将该连接返回给连接池,否则有连接泄露的危险.
3. 连接并验证
连接ldap服务器需要一个帐号。这个帐号是通过Connection.authenticate(String dn, String password) 来指定的。也就是,我们必须用这样的代码来验证并连接:
String dn = “uid=Frederick, ou=users, o=frederick.iteye.com”;
String password = “password”;
Connection.authenticate(dn, password);
4. 现在,我们就可以使用这个通过了验证的Connection 对象来做相关操作了。假设用来做操作的帐号是ldap_connection, 密码是password, 完整的代码如下:
import netscape.ldap.LDAPConnection;
import netscape.ldap.LDAPException;
import netscape.ldap.util.ConnectionPool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import fred.envoy.exception.util.LdapUtilsException;
public class LdapUtils {
private static final Log log = LogFactory.getLog(LdapUtils.class);
private static final String HOST = "frederick.iteye.com";
private static final int PORT = 10389;
private static final int MIN_CONN_SIZE = 1;
private static final int MAX_CONN_SIZE = 5;
private static final String USER_ID = "ldap_connection";
private static final String PASSWORD = "password";
private static final ConnectionPool connPool;
static {
try {
connPool = new ConnectionPool(MIN_CONN_SIZE, MAX_CONN_SIZE, HOST, PORT);
} catch (LDAPException e) {
String message = "Failed to init Ldap connection pool";
if (log.isErrorEnabled()) {
log.error(message, e);
}
throw new LdapUtilsException(message, e);
}
}
public static ConnectionPool getConnectionPool() {
return LdapUtils.connPool;
}
public static LDAPConnection getConnection() {
LDAPConnection conn = LdapUtils.getConnectionPool().getConnection();
try {
conn.authenticate(LdapUtils.getDnForUser(USER_ID), PASSWORD);
} catch (LDAPException e) {
String message = "Failed to authen the system ldap user";
if (log.isErrorEnabled()) {
log.error(message, e);
}
throw new LdapUtilsException(message, e);
}
return conn;
}
public static void closeConnection(LDAPConnection conn) {
LdapUtils.getConnectionPool().close(conn);
}
public static String getDnForUser(String userId) {
return new StringBuffer()
.append("uid=").append(userId).append(",")
.append("ou=users,o=frederick.iteye.com")
.toString();
}
}
5. 当然,也可以不用连接池,而是直接指定单个的连接。
LDAPConnection conn = new LDAPConnection();
try {
conn.connect(HOST, PORT);
} catch (LDAPException e1) {
throw new RuntimeException(e);
}
使用这样的单个连接有个好处,就是可以一次指定多个服务器,这样在连接的时候,会尝试一个一个的去试,直到成功连接到一个服务器。
LDAPConnection conn = new LDAPConnection();
try {
conn.connect("host1:port1 host2:port2 hostn:portn", LDAPv3.DEFAULT_PORT);
} catch (LDAPException e1) {
throw new RuntimeException(e);
}
其中,各个服务器必须符合“服务器名:端口名”的格式,而服务器之间用空格隔开。每个服务器可以指定自己的端口,而最后必须有一个默认端口参数。当某个服务器只指定了服务器名而没有指定端口的时候,连接会尝试使用指定的默认端口去连接