如果 java 客户端调用不同服务器上的远程 EJB,如何获取客户端 IP 地址?请注意,从服务器获取它很重要,因为客户端可能位于 NAT 防火墙后面,在这种情况下,我们需要公共 IP 地址。
注意:虽然它最好是一个通用的解决方案,但至少我可以使用一个从 JBoss 4.2.2 上的 EJB2 调用中检索 IP 地址的解决方案
如果 java 客户端调用不同服务器上的远程 EJB,如何获取客户端 IP 地址?请注意,从服务器获取它很重要,因为客户端可能位于 NAT 防火墙后面,在这种情况下,我们需要公共 IP 地址。
注意:虽然它最好是一个通用的解决方案,但至少我可以使用一个从 JBoss 4.2.2 上的 EJB2 调用中检索 IP 地址的解决方案
JBoss 社区 wiki 上的这篇文章正好解决了您的问题。在 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;
}
您是否尝试过: java.rmi.server.RemoteServer.getClientHost() ?
http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/server/RemoteServer.html#getClientHost()
我相信当前工作线程的名称包含服务器的 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);
}
感谢 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 "";