【问题标题】:Grizzly + Jersey Listening ONLY on LocalhostGrizzly + Jersey 仅在 Localhost 上收听
【发布时间】:2011-08-28 08:51:24
【问题描述】:

我正在使用带有 Grizzly 嵌入式版本的 Jersey,我只想在 localhost 上绑定/收听。我正在使用带有 create 调用的 GrizzlyWebContainerFactory 创建 ThreadSelector:

threadSelector = GrizzlyWebContainerFactory.create("http://127.0.0.1:8080/", initParams);

这可行,但我仍然能够从外部机器访问服务器。我怎样才能让它绑定到/只收听本地主机?

这是用于配置的东西,所以我不希望任何东西能够连接到这个服务器。

【问题讨论】:

    标签: java jersey grizzly


    【解决方案1】:

    我能够在 Jersey 2.3.1 中使用主机名 localhost 和嵌入式 Grizzly 版本来做到这一点:

    import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
    // ...
    GrizzlyHttpServerFactory.createHttpServer(
        URI.create("http://localhost:9580/my-app/")
    );
    

    测试结果:

    > curl -I http://myhost.com:9580/my-app
    curl: (7) couldn't connect to host
    

    而当使用 URI "http://0.0.0.0:9580/my-app/""http://myhost.com:9580/my-app/" 启动 Grizzly 服务器时,我可以使用它

    > curl -I http://myhost.com:9580/my-app
    HTTP/1.1 200 Not Found
    ...
    

    下表列出了在使用 GrizzlyHttpServerFactory 时哪些主机与哪些 URL 配合使用。据我所知,这并不奇怪:

    # For http://0.0.0.0:9575/my-app      | Works?
    curl -I http://0.0.0.0:9575/my-app    | Yes
    curl -I http://127.0.0.1:9575/my-app  | Yes
    curl -I http://localhost:9575/my-app  | Yes
    curl -I http://myhost.com:9575/my-app | Yes
                                          | 
    # For http://127.0.0.1:9575/my-app    | 
    # For http://localhost:9575/my-app    |
    curl -I http://0.0.0.0:9575/my-app    | Yes
    curl -I http://127.0.0.1:9575/my-app  | Yes
    curl -I http://localhost:9575/my-app  | Yes
    curl -I http://myhost.com:9575/my-app | No
                                          | 
    # For http://myhost.com:9585/my-app   | 
    curl -I http://0.0.0.0:9585/my-app    | No
    curl -I http://127.0.0.1:9585/my-app  | No
    curl -I http://localhost:9575/my-app  | No
    curl -I http://myhost.com:9585/my-app | Yes
    

    【讨论】:

      【解决方案2】:

      您可以轻松扩展 GrizzlyWebContainerFactory 以支持此要求(由于该类是最终的,我创建了一个自包含的实用程序,允许您将侦听套接字绑定到 localhost)。您可以将此实用程序用作:

      SelectorThread threadSelector = GrizzlyWebContainerFactoryUtil.create("http://127.0.0.1:8080/", initParams, true);
      

      将最后一个参数设置为 true 会强制它绑定到 localhost。我添加的唯一支持此要求的代码是:

      selectorThread.setAddress(InetAddress.getByName("localhost"));
      

      整个实用程序类如下所示:

      import com.sun.grizzly.http.SelectorThread;
      import com.sun.grizzly.http.servlet.ServletAdapter;
      import com.sun.grizzly.standalone.StaticStreamAlgorithm;
      import com.sun.grizzly.tcp.Adapter;
      import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
      import com.sun.jersey.api.container.ContainerException;
      import com.sun.jersey.api.core.ClasspathResourceConfig;
      import com.sun.jersey.spi.container.servlet.ServletContainer;
      
      import javax.servlet.Servlet;
      import java.io.File;
      import java.io.IOException;
      import java.net.InetAddress;
      import java.net.URI;
      import java.util.Map;
      
      public class GrizzlyWebContainerFactoryUtil {
      
        public static SelectorThread create(String u, Map<String, String> initParams, boolean localHostOnly)
                throws IOException, IllegalArgumentException {
            if (u == null)
                throw new IllegalArgumentException("The URI must not be null");
      
            return create(URI.create(u), initParams, localHostOnly);
        }
      
        public static SelectorThread create(URI u, Map<String, String> initParams, boolean localHostOnly) throws IOException {
          return create(u, ServletContainer.class, initParams, localHostOnly);
        }
      
        public static SelectorThread create(URI u, Class<? extends Servlet> c,
                                            Map<String, String> initParams, boolean localHostOnly) throws IOException {
          if (u == null)
            throw new IllegalArgumentException("The URI must not be null");
      
          ServletAdapter adapter = new ServletAdapter();
          if (initParams == null) {
            adapter.addInitParameter(ClasspathResourceConfig.PROPERTY_CLASSPATH,
              System.getProperty("java.class.path").replace(File.pathSeparatorChar, ';'));
          } else {
            for (Map.Entry<String, String> e : initParams.entrySet()) {
              adapter.addInitParameter(e.getKey(), e.getValue());
            }
          }
      
          adapter.setServletInstance(getInstance(c));
      
          String path = u.getPath();
          if (path == null)
            throw new IllegalArgumentException("The URI path, of the URI " + u +
              ", must be non-null");
          else if (path.length() == 0)
            throw new IllegalArgumentException("The URI path, of the URI " + u +
              ", must be present");
          else if (path.charAt(0) != '/')
            throw new IllegalArgumentException("The URI path, of the URI " + u +
              ". must start with a '/'");
      
          if (path.length() > 1) {
            if (path.endsWith("/"))
              path = path.substring(0, path.length() - 1);
            adapter.setContextPath(path);
          }
      
          return create(u, adapter, localHostOnly);
        }
      
        private static Servlet getInstance(Class<? extends Servlet> c) {
          try {
            return c.newInstance();
          } catch (Exception e) {
            throw new ContainerException(e);
          }
        }
      
      
        public static SelectorThread create(URI u, Adapter adapter, boolean localHostOnly)
          throws IOException, IllegalArgumentException {
          if (u == null)
            throw new IllegalArgumentException("The URI must not be null");
      
          // TODO support https
          final String scheme = u.getScheme();
          if (!scheme.equalsIgnoreCase("http"))
            throw new IllegalArgumentException("The URI scheme, of the URI " + u +
              ", must be equal (ignoring case) to 'http'");
      
          if (adapter instanceof GrizzlyAdapter) {
            GrizzlyAdapter ga = (GrizzlyAdapter) adapter;
            ga.setResourcesContextPath(u.getRawPath());
          }
      
          final SelectorThread selectorThread = new SelectorThread();
      
          selectorThread.setAlgorithmClassName(StaticStreamAlgorithm.class.getName());
      
          final int port = (u.getPort() == -1) ? 80 : u.getPort();
          selectorThread.setPort(port);
      
          if (localHostOnly) {
            selectorThread.setAddress(InetAddress.getByName("localhost"));
          }
          selectorThread.setAdapter(adapter);
      
          try {
            selectorThread.listen();
          } catch (InstantiationException e) {
            IOException _e = new IOException();
            _e.initCause(e);
            throw _e;
          }
          return selectorThread;
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2016-11-17
        • 1970-01-01
        • 2012-08-06
        • 2013-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-01
        相关资源
        最近更新 更多