【问题标题】:How can you get the calling ip address on an ejb call?如何在 ejb 调用中获取调用 IP 地址?
【发布时间】:2010-11-04 02:27:14
【问题描述】:

如果java客户端调用不同服务器上的远程EJB,如何获取客户端IP地址?请注意,从服务器获取它很重要,因为客户端可能位于 NAT 防火墙后面,在这种情况下,我们需要公共 IP 地址。

注意:虽然它最好是一个通用的解决方案,但至少我可以使用一个从 JBoss 4.2.2 上的 EJB2 调用中检索 IP 地址的解决方案

【问题讨论】:

    标签: java ip-address ejb


    【解决方案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);
            }
    

    【讨论】:

      【解决方案2】:

      感谢 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 "";
      

      【讨论】:

        【解决方案3】:

        JBoss 社区 wiki 上的This article 正好解决了您的问题。在 JBoss 5 之前,IP 地址显然必须从工作线程名称中解析出来。这似乎是在早期版本上执行此操作的唯一方法。这是代码 sn-p 做它(从上面的链接复制):

        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;
        }
        

        【讨论】:

        • 感谢您的回答。但是,工作线程名称中没有尖括号。也许这仅适用于 EJB 3。我必须以不同的方式解析它,但这让我到了正确的地方,所以我接受了这个答案。
        • 当前线程的名称包含服务器的 IP 地址,但不包含客户端的 IP,因为工作线程是池化的,而不是为每个请求创建的。
        【解决方案4】:

        你试过:java.rmi.server.RemoteServer.getClientHost() 吗?

        http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/server/RemoteServer.html#getClientHost()

        【讨论】:

        • 是的。在 JBoss 4.2.2 上,它会抛出一个异常,表明它不是 RMI 方法。我假设是因为 JBoss 在与侦听 RM​​I 响应的线程不同的线程上将消息分派给 EJB 实现。
        猜你喜欢
        • 2012-05-10
        • 1970-01-01
        • 2010-09-12
        • 2021-02-05
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多