Spring -Boot Jersey: разрешить Джерси обслуживать статический контент

Приложение использует JDK 8, Spring Boot и Spring Boot Jersey starter и упакован как WAR (хотя он локально выполняется через Spring плагин Boot Maven).

Что я хотел бы сделать, так это получить документацию, которую я создаю на лету (во время сборки) в качестве приветственной страницы.

Я попробовал несколько подходов:

  • позволяя Джерси обслуживать статическое содержимое, настроив application.properties правильный параметр инициализации, как описано здесь
  • введите metadata-complete=false web.xml, чтобы перечислить сгенерированный документ HTML в качестве файла приветствия.

Ничего из этого не получилось.

Я бы хотел избежать включения Spring MVC или создания ресурса Джерси только для обслуживания статического файла.

Любая идея?

Вот класс конфигурации в Джерси (я безуспешно пытался добавить там ServletProperties.FILTER_STATIC_CONTENT_REGEX):

@ApplicationPath("/")
@ExposedApplication
@Component
public class ResourceConfiguration extends ResourceConfig {

   public ResourceConfiguration() {
      packages("xxx.api");
      packages("xxx.config");
      property(ServerProperties.BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK, true);
      property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
   }
}

И вот Spring класс приложения загрузки (я попытался добавить application.properties с spring.jersey.init.jersey.config.servlet.filter.staticContentRegex=/.*html, но это не сработало, я не совсем уверен, что здесь должен быть ключ свойства):

@SpringBootApplication
@ComponentScan
@Import(DataConfiguration.class)
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Ответ 1

Позвольте мне сначала указать, что причина, по которой статический контент не будет обслуживаться, - это из-за стандартного отображения сервлета сервлета Джерси, который является /*, и вызывает все запросы. Таким образом, сервлет по умолчанию, обслуживающий статический контент, не может быть достигнут. Помимо решения ниже, другое решение - просто изменить отображение сервлета. Вы можете сделать это, либо аннотируя свой подкласс ResourceConfig с помощью @ApplicationPath("/another-mapping") либо установите свойство application.properties spring.jersey.applicationPath.


Что касается вашего первого подхода, взгляните на Jersey ServletProperties. Свойство, которое вы пытаетесь настроить, - FILTER_STATIC_CONTENT_REGEX. Говорится:

Свойство применимо только тогда, когда контейнер сервлета Джерри настроен на запуск в качестве фильтра, иначе это свойство будет проигнорировано

Spring Boot по умолчанию настраивает контейнер сервлетов Джерси в качестве сервлета (как указано здесь):

По умолчанию Джерси будет настроен как @Bean в @Bean типа ServletRegistrationBean именем jerseyServletRegistration. Вы можете отключить или переопределить этот bean-компонент, создав одно из ваших собственных с тем же именем. Вы также можете использовать фильтр вместо spring.jersey.type=filter установив spring.jersey.type=filter (в этом случае @Bean для замены или переопределения - это jerseyFilterRegistration).

Поэтому просто установите свойство spring.jersey.type=filter в свой application.properties, и он должен работать. Я проверил это.

И FYI, независимо от того, настроен ли он как сервлет-фильтр или сервлет, что касается Джерси, функциональность такая же.

В стороне, а не с помощью FILTER_STATIC_CONTENT_REGEX, где вам нужно настроить некоторое сложное регулярное выражение для обработки всех статических файлов, вы можете использовать FILTER_FORWARD_ON_404. На самом деле это то, что я использовал для тестирования. Я просто установил его в своем ResourceConfig

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages("...");
        property(ServletProperties.FILTER_FORWARD_ON_404, true);
    }
}

Ответ 2

Для тех, кто все еще не может заставить это работать, я выполнил ответ, предоставленный @peeskillet, и ему пришлось внести дополнительные изменения.

Ранее я создал следующий метод в Application.java.

@Bean
public ServletRegistrationBean jerseyServlet() {
    ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/*");
    registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName());
    return registration;
}

Проблема заключается в том, что он зарегистрировал сервлет для пути /*, а затем установил конфигурационный файл Jersey ResourceConfig.

Как только я удалил вышеуказанный метод и разместил аннотацию @Configuration в моем классе ResourceConfig, я заметил, что статический ресурс можно получить с помощью Spring Boot.

Для полноты, теперь это фрагмент моего ResourceConfig.

@Configuration
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        // Application specific settings
        property(ServletProperties.FILTER_FORWARD_ON_404, true);
    }
}

Это сообщение в блоге было полезно при определении разностного подхода для ResourceConfig.

Ответ 3

Ниже настройка работала для меня

Задавать

spring .jersey.type: filter

установить FILTER_FORWARD_ON_404

@Configuration 
        public class MyResourceConfig extends ResourceConfig  {

            public MyResourceConfig () {
                try {
                    register(XXX.class);
                    property(ServletProperties.FILTER_FORWARD_ON_404, true);

                } catch (Exception e) {
                    LOGGER.error("Exception: ", e);                   
                }
            }       

        } 

Примечание: используйте @Configuration вместо @component