我正在尝试将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没有部署在根上下文中,而是在/ api / *上下文中,如web.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.xml文件中定义Swagger servlet而不是使用BeanConfig,但仍然会出现相同的错误。我已经让Swagger以这种方式在使用Jersey 2的不同项目上工作,但遗憾的是当前项目必须保留在Jersey 1.19上。这是pom.xml文件中定义的Swagger依赖项:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey-jaxrs</artifactId>
<version>1.5.0</version>
</dependency>
任何帮助都将不胜感激。
答案 0 :(得分:2)
更新2:看起来版本1.5.8的swagger核心修复程序问题。有关详细信息,请参阅this commit。
更新:不是将Swagger资源添加为子资源,而是更轻松地覆盖@Path
映射。有关详细信息,请参阅解决方案2 。
我遇到了完全相同的问题。原因是Swagger资源被映射到根@Path("/") public class ApiListingResource
。
围绕它的一种简单且不灵活的方式是不来定义到根路径@Path("/")
的任何资源映射。
@Path
映射 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 {}
在Swagger包配置中添加my.api.package.swagger
而不是io.swagger.jaxrs.listing
。
其他解决方案是将Swagger移动到不同的路径,允许您的资源映射到您喜欢的任何位置。为此,您需要:
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);
}
如果您使用web.xml
param:
com.sun.jersey.config.property.packages
进行配置
<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>
BTW,我注意到<filter/>
中使用web.xml
配置Jersey的GF 3.1.2.2由于Grizzly related bug而无法与Swagger一起使用。
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; }
}
现在,您的Swagger描述符将位于http://hostname/app-path/swagger/swagger.json
之下,您仍然可以使用根资源。
它有点长,但有效!希望有所帮助。