Не может служить статическое содержание с пружинным ботинком и Джерси 2


Есть ли способ заставить пружинный ботинок с Джерси служить статическому содержанию? Я прошел через серию учебных пособий и примеров кода по интеграции Swagger в приложение Spring Boot. Я могу сделать так, чтобы он доставил основную развязность.json, но я не могу заставить Swagger UI работать.

Я даже не могу заставить его доставить простой hello.txt статический файл.

Соответствующие части моего пом.xml-это:

<!--Spring Boot-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Jersey -->
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-bean-validation</artifactId>
    <version>${jersey.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>${jersey.version}</version>
</dependency>

<!-- Swagger -->
<dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-jersey2-jaxrs</artifactId>
    <version>1.5.7</version>
</dependency>

И мой код:

@Configuration
@EnableAutoConfiguration
@ComponentScan({"com.xxxx"})
public class AdminApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(AdminApplication.class)
                .run(args);
    }

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




package com.xxxxxx.admin.config;
import com.xxxxxx.admin.resource.Status;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.spring.scope.RequestContextFilter;    
import io.swagger.jaxrs.config.BeanConfig;

public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(RequestContextFilter.class);
        packages("com"); // TODO needs more detailed level
        register(LoggingFilter.class);
        // Validation
        this.property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
        this.property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, true);
        configureSwagger();
    }

    private void configureSwagger() {
        register(io.swagger.jaxrs.listing.ApiListingResource.class);
        register(io.swagger.jaxrs.listing.SwaggerSerializers.class);
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0.0");
        beanConfig.setSchemes(new String[]{"http"});
        beanConfig.setHost("localhost:8080");
        beanConfig.setBasePath("/"); // tried other things like "/api", but doesn't change anything
        beanConfig.setResourcePackage("com.xxxxxx.admin");
        beanConfig.setPrettyPrint(true);
        beanConfig.setScan(true);
    }

}



//other imports
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Service
@Path("/status")
@Api(value = "status", description = "Check status")
public class Status {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation("Return status")
    public Response status() {
        return Response.ok("Up").build();
    }
}

Я также попытался заставить Джерси работать как фильтр (с spring.jersey.type=filter) и изменение шаблона сервлета Джерси, как указано в этот ответ, но это, кажется, ни на что не влияет.

@ApplicationPath("/rootPath")
public class JerseyConfig extends ResourceConfig {

У меня есть привет.файл txt под /src/главная/ресурсы/общественные и статические файлы интерфейса куражиться под /src/главная/ресурсы/общественные/чванство.

Как я уже сказал, мое приложение работает нормально, и получить http://localhost:8080/swagger.json показывает мне простую документацию json, но оба http://localhost:8080/hello.txt и http://localhost:8080/swagger/index.html return 404.

Я использую Jersey 2.8 и Spring Boot 1.3.0

2 3

2 ответа:

Я также попытался изменить шаблон сервлета Джерси

@ApplicationPath("/rootPath")
public class JerseyConfig extends ResourceConfig {

Способ настройки вашего приложения, @ApplicationPath не имеет значения. Причина, по которой он работал для этого ответа, который вы связали с, заключается в том, что автоматическая конфигурация Spring Boot устанавливает отображение сервлета, когда он извлекает значение @ApplicationPath из конфигурации ресурса.

В настоящее время вы не используете ServletRegistrationBean, предоставляемый Spring Boot, который выполняет это. Если ваша цель, используя ваш собственный ServletRegistrationBean, была такова что вы можете зарегистрировать свой ResourceConfig, Вы могли бы сделать то же самое просто с помощью любого

  1. аннотирование вашего ResourceConfig с помощью @Component, чтобы сделать его весенним Бобом, или
  2. Сделайте его пружинным Бобом в своем классе конфигурации

    @Bean
    public ResourceConfig config() {
        return new JerseyConfig();
    }
    

Spring Boot затем введет ваш ResourceConfig в JerseyAutoConfiguration, где он получит значение @ApplicationPath (если оно присутствует) на ResourceConfig и использует его для регистрации своего собственного ServletRegistrationBean.

Вы можете видеть JerseyAutoConfiguration чтобы получить представление о все, что вы получаете бесплатно, когда позволяете Spring Boot обрабатывать конфигурацию.

Если вы хотите сохранить свой текущий SpringRegistrationBean, просто измените путь, который вы используете. Вы используете /*, который упоминается как проблема в связанном ответе. Так что просто измените на /rooPath/*, Если это то, что вы хотите.

Это выглядит так же, как обычная проблема при использовании Spring MVC. Контейнер сервлета необходим в спецификации сервлета для реализации сервера по умолчанию с наименьшим приоритетом, который способен обслуживать статическое содержимое, расположенное вне папки WEB-INF. К сожалению, вы сопоставляете сервлет Jersey с "/*", что означает, что каждый URL-адрес будет отправлен в Jersey, а Jersey не знает, что делать со статическими URL-адресами.

Так что же можно (легко) сделать?
  • Сопоставьте сервлет Джерси с подпространство (скажем /api) и переместите все ваши контроллеры туда:

    ServletRegistrationBean registration =
        new ServletRegistrationBean(new ServletContainer(), "/api/*");
    ...
    beanConfig.setBasePath("/api/");
    

    И спросить GET http://localhost:8080/api/swagger.json

  • Только сопоставьте сервлет с *.json url:

    ServletRegistrationBean registration =
        new ServletRegistrationBean(new ServletContainer(), "*.json");