jjzjj

java - 嵌入式 jetty : Different ports for internally- and externally-visible endpoints?

coder 2023-09-02 原文

我有一个使用嵌入式 Jetty 作为服务器的 REST 应用程序。大多数端点需要公开可见(并内置适当的身份验证),但少数仅供内部使用。我想避免对这些进行身份验证的开销,而是使用防火墙来限制访问:

外部可见端点在端口 10000 上提供服务,外部防火墙保持打开状态。 内部可见的端点在端口 20000 上提供服务,外部防火墙阻止了该端口。

但是,我不知道如何使用嵌入式 Jetty 实现这一点。我已经尝试实例化两个 Server 对象,一个在端口 10000 上注册了适当的 servlet 处理程序,另一个在端口 20000 上注册了适当的 servlet 处理程序。但是,只有第二次启动的服务器实例有效;对第一个启动的端点托管的端点的请求导致 404 响应。

Jetty 文档讨论了如何使用 *.xml configurations 执行此操作,但不适用于嵌入式实例。

有什么想法或想法吗?还是有更好的方法来实现我所追求的内部/外部端点隔离?硬性要求是内部和外部端点都需要在同一个 JVM 中“运行”。


编辑

原来问题与使用 Guice 和 Guice-servlets 扩展有关(问题 618635)。如 James Kingsbery 的 answer 中所述,运行两个嵌入式 Jetty 实例工作正常下面。

Guice 使用在服务器上下文中注册的过滤器 (GuiceFilter) 来获取需要请求范围依赖注入(inject) (DI) 的请求,并构建需要 DI 的 servlet 和过滤器。不幸的是,它使用静态对象来管理与其关联的 servlet 和过滤器列表。

在典型的设置中,包含 GuiceFilter 的 guice-servlet.jar 包含在每个应用程序中,因此由每个应用程序的不同类加载器加载——一切正常。嵌入式 Jetty 则不然,基本上所有内容都由默认系统类加载器加载。

Guice 问题的求解

Guice 的最新主控(提交 fbbb52dcc92e)包含更新的 GuiceFilter,支持对 FilterPipeline 对象(导致问题的静态对象)的动态引用。不幸的是,注入(inject) FilterPipeline 实例的构造函数是包私有(private)的。因此,要使用它,您需要在公开该构造函数的 com.google.inject.servlet 包中创建一个包装类:

package com.google.inject.servlet;

import com.google.inject.Inject;

public class NonStaticGuiceFilter extends GuiceFilter {

    /**
     * Do not use. Must inject a {@link FilterPipeline} via the constructor.
     */
    @SuppressWarnings("unused")
    private NonStaticGuiceFilter() {
        throw new IllegalStateException();
    }

    @Inject
    public NonStaticGuiceFilter(FilterPipeline filterPipeline) {
        super(filterPipeline);
    }

}

要使用此类,请使用安装了 ServletModule 的注入(inject)器创建一个实例,并将其注册到 Jetty Context:

// Create the context handler
ServletContextHandler handler = new ServletContextHandler(myServer, "/context");

// Create the injector, registering your ServletModule
final Injector injector = Guice.createInjector(new MyServletModule());

// Add the Guice listener for this injector
handler.addEventListener(new GuiceServletContextListener() {
   @Override
   protected Injector getInjector() {
       return injector;
   }
});

// Filter all requests through Guice via NonStaticGuiceFilter.
// Guice will construct the FilterPipeline instance needed by
// NonStaticGuiceFilter.
handler.addFilter(
       new FilterHolder(injector
               .getInstance(NonStaticGuiceFilter.class)), "/*", null);

最佳答案

在开始使用嵌入式 Jetty 项目时,我常用的拐杖是 Wicket maven 原型(prototype)。这是一个基于该原型(prototype)的类,它应该可以满足您的大部分需求:

package net.kingsbery;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

public class Start {

    public static void main(String[] args) throws Exception {
            Server server = new Server();
            SocketConnector connector = new SocketConnector();

            // Set some timeout options to make debugging easier.                                                                                                                                
            connector.setMaxIdleTime(1000 * 60 * 60);
            connector.setSoLingerTime(-1);
            connector.setPort(10080);
            server.setConnectors(new Connector[] { connector });

            WebAppContext bb = new WebAppContext();
            bb.setServer(server);
            bb.setContextPath("/");
            bb.setWar("src/main/secret-webapp");

            server.addHandler(bb);

            Server server2 = new Server();
            SocketConnector connector2 = new SocketConnector();

            // Set some timeout options to make debugging easier.                                                                                                                                
            connector2.setMaxIdleTime(1000 * 60 * 60);
            connector2.setSoLingerTime(-1);
            connector2.setPort(20000);
            server2.setConnectors(new Connector[] { connector });

            WebAppContext bb2 = new WebAppContext();
            bb2.setServer(server);
            bb2.setContextPath("/");
            bb2.setWar("src/main/webapp");



            server.addHandler(bb);
            server2.addHandler(bb2);

            try {
                    server.start();
                    server2.start();
            } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(100);
            }
    }
}

如果您使用其他处理程序,请将其替换为 webapp 处理程序。

话虽如此,我不确定这是不是正确的做法。

关于java - 嵌入式 jetty : Different ports for internally- and externally-visible endpoints?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9074704/

有关java - 嵌入式 jetty : Different ports for internally- and externally-visible endpoints?的更多相关文章

随机推荐