Встроенная пристань: разные порты для внутренних и внешних видимых оконечных точек? - PullRequest
11 голосов
/ 31 января 2012

У меня есть REST-приложение, которое использует встроенный Jetty в качестве сервера. Большинство конечных точек должны быть общедоступными (и иметь соответствующую встроенную аутентификацию), но некоторые предназначены только для внутреннего использования. Я бы хотел избежать излишней аутентификации на них и вместо этого использовать брандмауэр для ограничения доступа:

Внешне видимые конечные точки обслуживаются через порт 10000, который внешний брандмауэр оставляет открытым. Внутренне видимые конечные точки обслуживаются через порт 20000, который блокирует внешний брандмауэр.

Однако я не могу понять, как этого добиться с помощью встроенной Jetty. Я попытался создать два объекта Server, один на порту 10000 с соответствующими зарегистрированными обработчиками сервлетов и один на порту 20000 с соответствующими зарегистрированными обработчиками сервлетов. Однако работает только экземпляр сервера, запущенный вторым; запросы к конечным точкам, размещенным первым запустившимся, приводят к 404 ответам.

В документации Jetty говорится о том, как сделать это с *. Xml-конфигурациями , но не для встроенного экземпляра.

Есть мысли или идеи? Или есть лучший способ добиться внутренней / внешней изоляции конечной точки, который я ищу? Жесткое требование заключается в том, что внутренние и внешние конечные точки должны «работать» в одной и той же JVM.


Редактировать

Оказывается, что проблема была связана с использованием Guice и расширением Guice-servlets (проблемы 618 и 635 ). Запуск двух встроенных экземпляров Jetty работает нормально, как описано в ответе Джеймса Кингсбери ниже.

Guice использует фильтр (GuiceFilter), зарегистрированный в контексте сервера, для получения запросов, требующих внедрения зависимостей в области запросов (DI), и для создания сервлетов и фильтров, требующих DI. К сожалению, он использует статический объект для управления списком сервлетов и связанных с ним фильтров.

В типичной настройке файл guice-servlet.jar, содержащий GuiceFilter, включен для каждого приложения и, таким образом, загружается различным загрузчиком классов для каждого приложения - и все работает нормально. Не так со встроенным Jetty, где по умолчанию все загружается системным загрузчиком классов по умолчанию.

Решение проблемы Guice

Последний мастер (commit fbbb52dcc92e) Guice содержит обновленный GuiceFilter с поддержкой динамической ссылки на объект FilterPipeline (статический объект, вызывающий проблемы). К сожалению, конструктор для внедрения экземпляра FilterPipeline является закрытым для пакета. Итак, чтобы использовать его, вам нужно создать класс-оболочку в пакете 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 и зарегистрируйте его на 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);

1 Ответ

5 голосов
/ 31 января 2012

Моя обычная опора в начале работы со встроенным проектом Jetty - архетип Wicket maven.Вот класс, основанный на этом архетипе, который должен делать в значительной степени то, что вам нужно:

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

Если вы используете какой-то другой обработчик, замените его на обработчик веб-приложения.

Как говорится,Я не уверен, что это правильный способ сделать это.

...