2015-06-22 104 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

相關問題