无法使用Spring Boot和Jersey 2提供静态内容

时间:2016-02-11 14:52:43

标签: java spring-boot swagger jersey-2.0 swagger-ui

有没有办法使用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)并按照this answer中的说明更改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

2 个答案:

答案 0 :(得分:2)

  

我也尝试过更改Jersey的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();
    }
    
  3. 然后,

    Spring Boot将ResourceConfig注入JerseyAutoConfiguration@ApplicationPath将获得ResourceConfig上的ServletRegistrationBean值(如果存在),并使用它进行注册它自己的SpringRegistrationBean

    当你让Spring Boot处理配置时,你可以看到JerseyAutoConfiguration来了解免费获得的所有内容。

    如果您想保留当前的/*,只需更改您正在使用的路径即可。您正在使用/rooPath/*,这被提到是链接答案中的问题。如果那就是你想要的,那么只需改为{{1}}。

答案 1 :(得分:2)

使用Spring MVC时,它看起来与常见问题相同。每个servlet规范都需要一个servlet容器来实现具有最低优先级的默认服务器,该服务器能够提供位于WEB-INF文件夹之外的静态内容。 不幸的是,您将Jersey servlet映射到<?php $data = $_POST['this'])); echo "Today is $data"; ?> ,这意味着每个URL都将提交给Jersey,而Jersey不知道如何处理静态URL。

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

  • 将Jersey servlet映射到子路径(比如"/*")并将所有控制器移动到那里:

    /api

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

  • 仅将servlet映射到GET http://localhost:8080/api/swagger.json网址:

    *.json