有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Jersey 1.19版本的java Swagger JAXRS出现“冲突URI模板”错误

我正在尝试将Swagger添加到使用Jersey 1.19的现有应用程序中。为了向应用程序添加Swagger,我一直遵循以下指南:https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-1.X-Project-Setup-1.5

在Apache Tomcat上部署应用程序时,出现以下错误:

SEVERE: Conflicting URI templates. The URI template / for root resource class io.swagger.jaxrs.listing.ApiListingResource and the URI template / transform to the same regular expression (/.*)?

奇怪的是,Jersey servlet并没有部署在根上下文中,而是部署在web中显示的/api/*上下文中。xml文件:

<servlet>
    <servlet-name>MyApp Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>app.MyApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>MyApp Service</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

MyApplication类的定义如下:

public class MyApplication extends Application {

private final Set<Object> singletons = new HashSet<Object>();
private final Set<Class<?>> classes = new HashSet<Class<?>>();

public MyApplication() {

    MyResource resource= new MyResource();

    singletons.addAll(Arrays.asList(resource));

    BeanConfig beanConfig = new BeanConfig();
    beanConfig.setBasePath("/api");
    beanConfig.setResourcePackage(getClass().getPackage().getName());
    beanConfig.setTitle("REST API");
    beanConfig.setVersion("1.0.0");
    beanConfig.setScan(true);

    classes.add(io.swagger.jaxrs.listing.ApiListingResource.class);
    classes.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
}

@Override
public Set<Class<?>> getClasses() {
    return classes;
}

@Override
public Set<Object> getSingletons() {
    return singletons;
}}

我尝试过其他配置,比如在web中定义Swagger servlet。xml文件,而不是使用BeanConfig,但仍然会发生相同的错误。我已经在另一个使用Jersey 2的项目中以这种方式工作,但不幸的是,当前项目必须保留Jersey 1.19。以下是pom中定义的招摇过市依赖项。xml文件:

<dependency>
  <groupId>io.swagger</groupId>
  <artifactId>swagger-jersey-jaxrs</artifactId>
  <version>1.5.0</version>
</dependency>

任何帮助都将不胜感激


共 (1) 个答案

  1. # 1 楼答案

    更新2:看起来像是swagger core的1.5.8版解决了这个问题。详见this commit


    更新:与其将Swagger资源添加为子资源,不如直接覆盖@Path映射。有关详细信息,请参见解决方案2


    我也面临着同样的问题。这是因为Swagger资源被映射到根@Path("/") public class ApiListingResource


    解决方案1-无并发映射

    一种简单且不灵活的方法是定义任何到根路径@Path("/")的资源映射


    解决方案2-覆盖@Path映射

    2.1覆盖招摇类

    ApiListingResource应该获得一个新的@Path映射

    package my.api.package.swagger
    
    import javax.ws.rs.Path;
    
    @Path("swagger")
    public class ApiListingResource extends io.swagger.jaxrs.listing.ApiListingResource {}
    

    SwaggerSerializers应该得到新的包

    package my.api.package.swagger;
    
    import javax.ws.rs.ext.Provider;
    
    @Provider
    public class SwaggerSerializers extends io.swagger.jaxrs.listing.SwaggerSerializers {}
    

    2.2配置覆盖类

    在Swagger包配置中添加my.api.package.swagger而不是io.swagger.jaxrs.listing


    解决方案3-将招摇过市资源作为子资源

    另一个解决方案是将Swagger移动到另一条路径,允许您的资源映射到任何您喜欢的地方。要实现这一点,您需要:

    3.1从提供程序类中删除ApiListingResource

    如果子类Application

    public MyApplication() {
        //init BeanConfig
        //add your resource classes
    
        //classes.add(io.swagger.jaxrs.listing.ApiListingResource.class);
        classes.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
    }
    

    如果使用com.sun.jersey.config.property.packages参数通过web.xml进行配置:

    <servlet>
        <servlet-name>your-rest-api</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>
                {your_application_packages},
                <! io.swagger.jaxrs.json, >
                <! io.swagger.jaxrs.listing >
            </param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.property.classnames</param-name>
            <param-value>
                io.swagger.jaxrs.listing.SwaggerSerializers,
                io.swagger.jaxrs.json.JacksonJsonProvider
            </param-value>
        </init-param>
    </servlet>
    

    顺便说一句,我注意到GF 3.1.2.2在web.xml中使用<filter/>配置了Jersey,但由于Grizzly related bug的原因,它不适用于Swagger

    3.2将ApiListingResources作为子资源添加到您的资源之一

    @Path("/") 
    class RootResource {
        @Context ServletContext context;
    
        @Path("/swagger")
        public ApiListingResource swagger() {
            return new ApiListingSubResource(context);
        }
    }
    

    由于ApiListingResource现在不由泽西岛管理,因此它不会被ServletContext注入。要解决这个问题,必须将其作为构造函数参数传递,并为该子类ApiListingResource提供适当的构造函数:

    // context has 'default' visibility
    // so we need to stay in the same package 
    // to be able to access it
    package io.swagger.jaxrs.listing;
    
    import javax.servlet.ServletContext;
    
    public class ApiListingSubResource extends ApiListingResource {
        public ApiListingSubResource(ServletContext sc) { this.context = sc; }
    }
    

    现在,您的招摇过市描述符将位于http://hostname/app-path/swagger/swagger.json下,您仍然可以使用根资源

    这是一个稍微长一点的方式,但工作!希望有帮助