2009-06-18 124 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); 
     }