Embedded Jetty: разные порты для внутренних и внешних конечных точек?

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

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

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

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

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


Edit

Оказывается, проблема была связана с использованием 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 Контекст :

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

11
задан Community 23 May 2017 в 12:10
поделиться