2016-02-11 137 views
3

有沒有什麼辦法讓Jersey使用Spring Boot來提供靜態內容?我已經通過一系列教程和代碼示例將Swagger集成到Spring Boot的應用程序中。我可以讓它提供基本的swagger.json,但我無法讓Swagger UI工作。使用Spring Boot和Jersey 2無法提供靜態內容

我甚至無法提供一個簡單的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(); 
    } 
} 

我也試圖使澤西運行作爲一個過濾器(帶spring.jersey.type=filter)和新澤西變化的Servlet模式如this answer中所述,但這似乎不影響任何內容。

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

我下/ src目錄/主/資源/公共和揚鞭UI的靜態文件在/ src目錄/主/資源/公/招搖一個hello.txt的文件。

正如我所說的,我的應用程序工作正常,和GET http://localhost:8080/swagger.json我展示了普通JSON文件,但兩者http://localhost:8080/hello.txthttp://localhost:8080/swagger/index.html回報404

我使用的是2.8新澤西州和Spring 1.3.0引導

回答

2

我也試着更改球衣的Servlet模式

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

你的方式配置你的應用程序,@ApplicationPath並不重要。它爲this answer you linked to工作的原因是因爲Spring Boot自動配置在從資源配置中提取@ApplicationPath值時設置servlet映射。

您目前沒有使用Spring Boot提供的ServletRegistrationBean來完成此操作。如果你的目標,用自己的ServletRegistrationBean,是讓您可以註冊ResourceConfig,你有可能會簡單地通過任何

  1. 做了同樣的註解與ResourceConfig@Component使它一個Spring bean,或
  2. 使它成爲一個Spring bean配置中的類

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

春天開機時會再注入你的ResourceConfigJerseyAutoConfiguration,在那裏它將得到值(如果有的話)ResourceConfig,並用它來註冊自己的ServletRegistrationBean

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

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

+1

這是一個很好的答案,謝謝!但是有些奇怪。我設置了'spring.jersey.type = filter'和'spring.jersey.application-path = rootPath',並且一切都很好:靜態內容被提供,應用端點被移動到'rootPath /'並正確回覆。但是,如果我只設置'spring.jersey.type = filter'而不是'spring.jersey.application-path',則靜態內容不再可用。根據鏈接答案中的選項1,將球衣設置爲過濾器應該足夠了。我錯過了什麼? – user384729

+0

因爲您仍然需要將屬性'ServletProperties.FILTER_FORWARD_ON_404'設置爲'true'。看到[這個答案](http://stackoverflow.com/a/29670751/2587435) –

+0

我忘了提到你是對的,我添加了自己的'ServletRegistrationBean'來註冊'ResourceConfi'g。我遵循你的建議,並用'@ Component'註釋了'ResourceConfig',並不再使用我自己的'ServletRegistrationBean'。 – user384729

2

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

那麼可以(容易)完成什麼?

  • 地圖澤西servlet來的子路徑(比如/api),並將所有你控制人不存在:

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

    ,並要求GET http://localhost:8080/api/swagger.json

  • 只有該servlet映射到*.json網址:

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