如何让Swagger识别@ApplicationPath?基于swagger-jaxrs 1.5.18
解决Swagger-JAXRS 1.5.18路径前缀缺失问题
这种情况我维护老项目时也碰到过,Swagger 1.5.x确实有个小坑——它默认不会自动把@ApplicationPath的路径前缀合并到生成的API路径里。不用改动现有注解的话,有几个靠谱的方案可以试试:
方案一:配置Swagger的BasePath参数(最简单直接)
Swagger允许通过配置手动指定API的基础路径,刚好可以补上@ApplicationPath的前缀。
方式1:Web.xml配置
如果项目用web.xml管理Servlet,给Swagger的配置Servlet加一个初始化参数:
<servlet> <servlet-name>swagger-jaxrs-config</servlet-name> <servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class> <init-param> <!-- 这里填你的完整基础路径:/api/docs --> <param-name>swagger.api.basepath</param-name> <param-value>/api/docs</param-value> </init-param> <init-param> <param-name>swagger.resource.package</param-name> <param-value>com.your.project.resource</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>swagger-jaxrs-config</servlet-name> <url-pattern>/swagger.json</url-pattern> </servlet-mapping>
方式2:Java代码配置(无web.xml场景)
创建一个Servlet上下文监听器,手动初始化Swagger的BeanConfig:
import io.swagger.jaxrs.config.BeanConfig; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class SwaggerInitializer implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { BeanConfig beanConfig = new BeanConfig(); beanConfig.setVersion("1.0.0"); beanConfig.setSchemes(new String[]{"http"}); beanConfig.setHost("localhost:8080"); // 补上ApplicationPath的前缀 beanConfig.setBasePath("/api/docs"); // 扫描你的资源类包 beanConfig.setResourcePackage("com.your.project.resource"); beanConfig.setScan(true); } }
方案二:自定义ApiListingResource(动态适配路径)
如果需要动态获取@ApplicationPath的值(比如多环境路径不同),可以重写Swagger的默认资源类,手动合并路径:
- 自定义
ApiListingResource:
import io.swagger.jaxrs.listing.ApiListingResource; import io.swagger.models.Swagger; import javax.inject.Inject; import javax.ws.rs.core.Application; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.UriInfo; public class CustomApiListingResource extends ApiListingResource { @Inject private Application jaxrsApplication; @Override protected Swagger process(UriInfo uriInfo, HttpHeaders headers, String swaggerJson) { Swagger swagger = super.process(uriInfo, headers, swaggerJson); // 获取@ApplicationPath的配置值 String applicationPath = jaxrsApplication.getApplicationPath(); if (applicationPath != null && !applicationPath.isEmpty()) { // 合并基础路径和ApplicationPath String fullBasePath = uriInfo.getBaseUri().getPath() + applicationPath; swagger.setBasePath(fullBasePath); } return swagger; } }
- 在你的Application类里注册这个自定义资源:
import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import java.util.HashSet; import java.util.Set; @ApplicationPath("/docs") public class MyJaxrsApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); // 注册自定义的ApiListingResource classes.add(CustomApiListingResource.class); // 注册Swagger序列化类 classes.add(io.swagger.jaxrs.listing.SwaggerSerializers.class); // 注册你的业务资源类 classes.add(MyDocsResource.class); return classes; } }
方案三:Spring Boot整合场景(可选)
如果是Spring Boot项目,直接在配置文件里指定Swagger的基础路径:
# application.properties swagger.base-path=/api/docs
注:该方式需要确保你的Swagger整合starter支持此配置,老版本可能需要配合springfox使用。
内容的提问来源于stack exchange,提问作者GuitarStrum




