簡體   English   中英

無法使用Spring Boot和Jersey 2提供靜態內容

[英]Can't serve static content with Spring Boot and Jersey 2

是否有任何方法可以使用Jersey提供Spring Boot靜態內容? 我已經完成了將Swagger集成到Spring Boot應用程序中的一系列教程和代碼示例。 我可以讓它提供基本的swagger.json,但我不能讓Swagger UI工作。

我甚至無法提供一個簡單的hello.txt靜態文件。

我的pom.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();
    }
}

我還嘗試將Jersey運行為過濾器(使用spring.jersey.type=filter )並更改Jersey的servlet模式, 如此答案中所述 ,但這似乎不會影響任何事情。

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

我在/ src / main / resources / public下有一個hello.txt文件,在/ src / main / resources / public / swagger下有一個Swagger UI的靜態文件。

正如我所說,我的應用程序工作正常,並且GET http:// localhost:8080 / swagger.json向我展示了普通的json文檔,但http:// localhost:8080 / hello.txthttp:// localhost:8080 /swagger/index.html返回404。

我正在使用Jersey 2.8和Spring Boot 1.3.0

我也試過改變澤西島的servlet模式

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

您配置應用程序的方式與@ApplicationPath無關。 與您鏈接的答案有效的原因是,Spring Boot自動配置在從資源配置中提取@ApplicationPath值時設置servlet映射。

您目前沒有使用Spring Boot提供的ServletRegistrationBean來完成此任務。 如果您通過使用自己的ServletRegistrationBean來實現目標,那么您可以注冊您的ResourceConfig ,您可以簡單地通過

  1. 使用@Component注釋ResourceConfig以使其成為Spring bean,或者
  2. 使它成為配置類中的Spring bean

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

然后,Spring Boot會將您的ResourceConfig注入JerseyAutoConfiguration ,它將在ResourceConfig上獲取@ApplicationPath值(如果存在),並使用它來注冊自己的ServletRegistrationBean

當您讓Spring Boot處理配置時,您可以看到JerseyAutoConfiguration以了解您免費獲得的所有內容。

如果您想保留當前的SpringRegistrationBean ,只需更改您正在使用的路徑。 您正在使用/* ,這被提到是鏈接答案中的問題。 所以只需更改為/rooPath/*如果這是你想要的。

使用Spring MVC時,它看起來與常見問題相同。 每個servlet規范都需要一個servlet容器來實現具有最低優先級的默認服務器,該服務器能夠提供位於WEB-INF文件夾外部的靜態內容。 不幸的是,您將Jersey servlet映射到"/*" ,這意味着每個URL都將提交給Jersey,而Jersey不知道如何處理靜態URL。

那么可以(輕松)完成什么?

  • 將Jersey servlet映射到子路徑(比如/api )並將所有控制器移動到那里:

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

    並詢問GET http://localhost:8080/api/swagger.json

  • 僅將servlet映射到*.json URL:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM