我有一个网页页面来管理活动目录组,在这个页面的初始化中,我用jndi连接到ldap,并在http会话中保存ldap上下文。
这是我如何连接到ldap:
public static LdapContext connectToLdap(String host,
String userDN, String userPassword,
boolean ssl) throws Exception {
System.out.println("connectToLdap");
String hostPrefix = "ldap";
String ldapPort = "389";
if (ssl) {
hostPrefix = "ldaps";
ldapPort = "636";
}
String providerUrl = hostPrefix + "://" + host + ":" + ldapPort;
//System.out.println("####### LDAP URL: " + providerUrl);
LdapContext ldapContext;
Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, providerUrl);
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, userDN);
ldapEnv.put(Context.SECURITY_CREDENTIALS, userPassword);
ldapEnv.put("com.sun.jndi.ldap.read.timeout", 1000 * 10 + "");
if (ssl) {
ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
}
ldapEnv.put(Context.REFERRAL, "ignore");
try {
ldapContext = new InitialLdapContext(ldapEnv, null);
System.out.println("success connection to ldap");
return ldapContext;
} catch (Exception e) {
System.out.println("failure connection to ldap");
e.printStackTrace();
return null;
}
}
问题:我注意到有时10-15分钟后,活动目录组的检索失败,我得到例外:
javax.naming.CommunicationException: Connection reset [Root exception is java.net.SocketException: Connection reset]
任何想法为什么?请告知我为什么会遇到此问题以及如何解决此问题。
答案 0 :(得分:1)
不要将LdapContext放在HTTP会话中,它不会实现Serializable接口,因此不能保证它可以存储/恢复到会话。
考虑一下,如果会话要存储在数据库中或者复制到另一个服务器,LdapContext会被转换为字节,以及它引用的任何套接字描述符,当你从字节中恢复时它会如何工作?
如果你需要长期联系,请将它放在一个单身人士中。
除此之外,服务器和网络设备通常会关闭[他们认为的]非活动网络连接,因此任何长期连接都需要进行测试或保持活动状态。
如果它仍然相关我会建议您使用({3}} UnboundID LDAP SDK for Java和connection的(GPLv2,LGPLv2.1许可)pooling(无关联)比运送的JNDI实现好一点。