2009-06-18 119 views
2

如果一個java客戶端在另一個服務器上調用遠程EJB,如何獲得客戶端IP地址?請注意,從服務器獲取它很重要,因爲客戶端可能位於NAT防火牆後面,在這種情況下,我們需要公共IP地址。如何在ejb呼叫中獲得呼叫IP地址?

注意:雖然將優選一個通用的解決方案,至少我可以用一個從在JBoss 4.2.2

回答

2

JBoss的社區維基地址正是您的問題This article。在JBoss 5之前,IP地址顯然必須從工作者線程名稱中解析出來。這似乎是在早期版本上完成它的唯一方法。這是它的代碼片段(從上面的鏈接複製):

private String getCurrentClientIpAddress() { 
    String currentThreadName = Thread.currentThread().getName(); 
    System.out.println("Threadname: "+currentThreadName); 
    int begin = currentThreadName.indexOf('[') +1; 
    int end = currentThreadName.indexOf(']')-1; 
    String remoteClient = currentThreadName.substring(begin, end); 
    return remoteClient; 
} 
+0

感謝您的回答。雖然在工作線程名稱中沒有尖括號。也許這隻適用於EJB 3。我不得不以不同的方式解析它,但是這讓我得到了正確的地方,所以我接受了這個答案。 – Yishai 2009-06-29 16:50:35

0

感謝MicSim,我瞭解到線程名稱存儲IP地址。在JBoss中4.2.2 EJB2項目線程名看起來像這樣:

HTTP-127.0.0.1-8080-2

(我假定HTTP是可選的,這取決於實際使用的協議)。

然後可以用正則表達式作爲這樣解析:

Pattern pattern = Pattern.compile("\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b"); 
    Matcher matcher = pattern.matcher(Thread.currentThread().getName()); 
    if (matcher.find()) { 
     return matcher.group(); 
    } 
    return ""; 
1

我認爲,當前的工作線程的名稱中包含的服務器的IP地址,而不是客戶端的IP,因爲線程池,而比爲每個呼叫創建的。在JBoss 4中,可以使用以下解決方法獲取客戶端的IP地址:

 try { 
      //Reflection is used to avoid compile-time dependency on JBoss internal libraries 
      Class clazz = Class.forName("org.jboss.web.tomcat.security.HttpServletRequestPolicyContextHandler"); 
      Field requestContextField = clazz.getDeclaredField("requestContext"); 
      requestContextField.setAccessible(true); 
      ThreadLocal ctx = (ThreadLocal) requestContextField.get(null); 
      ServletRequest req = ((ServletRequest) ctx.get()); 
      return req==null?null:req.getRemoteAddr(); 
     } catch (Exception e) { 
      LOG.log(Level.WARNING, "Failed to determine client IP address",e); 
     }