2015-06-22 61 views
1

我很确定我知道这个问题,我只是不知道如何解决它。如何解决java.net.SocketException:连接重置

我有一个java EE应用程序在ldap中进行搜索。我初始化上下文与GETENV:

(注*:代码是有点简化了理解的目的)

InitialDirContext ctx = new InitialDirContext(getEnv(CONFIG_MAP); //CONFIG_MAP contains the host, mng_dn, mng_pw 

public static Hashtable<String, String> getEnv(Map<String, String> configMap) { 

    // Hashtable for environmental information 
    Hashtable<String, String> env = new Hashtable<String, String>(); 

    // Specify which class to use for our JNDI Provider 
    env.put(Context.INITIAL_CONTEXT_FACTORY, INITCTX); 

    // Specify the host and port to use for directory service 
    env.put(Context.PROVIDER_URL, configMap.get(HOST)); 

    // Security Information 
    env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
    env.put(Context.SECURITY_PRINCIPAL, configMap.get(MGR_DN)); 
    env.put(Context.SECURITY_CREDENTIALS, configMap.get(MGR_PW)); 
    env.put("java.naming.ldap.attributes.binary", "objectSID"); 

    return env; 
} 

我不知道这是不好的做法,但为了防止从初始化之前发生的每搜索我做了一个初始化函数,它:

if(Util.ctx == null){ 
    Util.init() 
} 

所以,问题来自于这里。我的应用程序将工作大约30分钟(不确定的时间),然后搜索将不再工作,我会在我的控制台中得到连接重置错误。我的猜测是连接是“关闭的”,并且它不再执行初始化,因为ctx不为空。我需要帮助来找出要添加到我的if语句以防止发生此错误。也许类似

if(Util.ctx == null || Util.ctx.isClosed()){ 
    Util.init(); 
} 

我读了InitialDirContext并找不到我需要的东西。

回答

1

怎么样设置无超时如下:

// Set up environment for creating initial context 
Hashtable env = new Hashtable(11); 
env.put(Context.INITIAL_CONTEXT_FACTORY, 
    "com.sun.jndi.ldap.LdapCtxFactory"); 
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial"); 

// Specify time-out to be infinite time . make it like never expired 
env.put("com.sun.jndi.ldap.connect.timeout", "-1"); 

// Create initial context 
DirContext ctx = new InitialDirContext(env); 

而且如下需要时您可以在以后将其关闭:

finally { 

     if (obj instanceof Context) { 

      Context ctx = (Context) obj; 
      try { 
       ctx.close(); 
      } 
      catch (Exception e) { 

      } 

     } 
    } 

检查了这一点: https://docs.oracle.com/javase/tutorial/jndi/newstuff/readtimeout.html

+0

这种方式应用程序服务器将始终保持连接到我的LDAP服务器,除非我重新启动应用程序服务器?难道这从长远来看不会造成问题吗? – trixrabbit

+0

我认为你是对的。但问题是,您可以通过添加finally try catch块来关闭连接并在需要时将其返回到连接池。我的意思是你需要明确地在你需要的地方关闭它,看看更新后的答案。不知道这是否有帮助。 – Jegg

+0

它确实有帮助,但我无法弄清楚什么时候我想关闭它。我的应用程序是我们内部网的一个Web应用程序,它允许用户搜索其他人的信息(电子邮件,电话等),例如目录。我在加载搜索页面时执行init()。我只在本地主机上测试过,所以我不确定这将如何与许多用户一起工作。我认为服务器在用户到达搜索页面时执行一次init(),然后未来的用户将跳过init()。 – trixrabbit

1

不要尽量保持重复使用相同的上下文。每次需要时都可以获得一个新的。服务器在任何时候感觉都会关闭空闲连接,并且isClosed()在完成时不会告诉您。

您可以使用JNDI LDAP连接池功能来保存连接。

+0

问题是,我不知道在web应用程序中初始化上下文的位置,而不必在更改页面和使用一些简单的搜索函数时重新上载自己20次。我用我的表单的构造函数中的init()来进行搜索。我试着把它放在我的servlet的doGet()中,但它似乎不是一个更好的解决方案。它似乎并没有减慢应用程序的速度,但我只是认为它没有理由反复加载相同的信息 – trixrabbit

相关问题