2016-02-11 106 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");