SpringFox部署Tomcat时Context Path重复及API文档路径异常问题
解决SpringFox在不同部署环境下URL生成重复的问题
这个问题我之前在Spring Boot+SpringFox的项目里也碰到过,3.0.0-SNAPSHOT版本确实在处理context path的时候有一些环境适配的坑,给你几个经过验证的解决思路:
1. 用Spring Profiles区分环境配置(最优雅的方案)
核心思路是给自托管(开发环境)和Tomcat部署(生产环境)分别配置不同的context path和SpringFox参数,从根源避免路径重复:
开发环境(application-dev.yml)
清空context path,让Swagger UI和api-docs直接通过根路径访问:
server: servlet: context-path: "" springfox: documentation: swagger-ui: base-url: / openapi: v3: path: /v2/api-docs
生产环境(application-prod.yml)
设置正确的应用路径,让SpringFox的文档路径和应用路径完全对齐:
server: servlet: context-path: /my-app-1.0.0 springfox: documentation: swagger-ui: base-url: /my-app-1.0.0 openapi: v3: path: /my-app-1.0.0/v2/api-docs
配置Docket时动态适配路径
在Swagger配置类里,根据当前激活的profile设置pathMapping,确保API路径在两个环境下都正确:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Autowired private Environment environment; @Bean public Docket api() { // 判断当前运行环境 boolean isDevEnv = Arrays.stream(environment.getActiveProfiles()) .anyMatch(profile -> profile.equals("dev")); // 开发环境用根路径,生产环境用配置的context path String basePath = isDevEnv ? "/" : "/my-app-1.0.0"; return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.your.package")) // 替换成你的API实际包路径 .paths(PathSelectors.any()) .build() .pathMapping(basePath); } }
启动时,开发环境加参数--spring.profiles.active=dev,生产环境加--spring.profiles.active=prod即可自动适配配置。
2. 手动修正Docket的路径映射(快速临时方案)
如果不想引入多profile配置,也可以直接在Docket里手动处理重复路径的问题:
@Bean public Docket api() { String contextPath = ServletUriComponentsBuilder.fromCurrentContextPath().build().getPath(); // 处理Tomcat部署时的路径重复问题 if (contextPath.contains("/my-app-1.0.0/my-app-1.0.0")) { contextPath = "/my-app-1.0.0"; } // 开发环境清空不必要的路径前缀 else if (contextPath.equals("/my-app-1.0.0")) { contextPath = "/"; } return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.your.package")) .paths(PathSelectors.any()) .build() .pathMapping(contextPath); }
3. 覆盖SpringFox的ServletContext路径获取逻辑(特殊场景备用)
如果上面的方案都无法解决问题,可以尝试自定义ServletContextProvider来强制修正路径,这个方法偏hack,适合特殊场景:
@Component public class CustomServletContextProvider implements ServletContextProvider { @Override public ServletContext getServletContext() { ServletContext context = null; RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); if (attributes instanceof ServletRequestAttributes) { context = ((ServletRequestAttributes) attributes).getRequest().getServletContext(); } if (context != null && context.getContextPath().contains("/my-app-1.0.0/my-app-1.0.0")) { // 强制设置正确的context path context.setContextPath("/my-app-1.0.0"); } return context; } }
这些方案里,优先推荐Spring Profiles的方式,既能清晰区分环境配置,也能避免硬编码路径的问题,后续维护起来更方便。
内容的提问来源于stack exchange,提问作者Eli Pulsifer
相关产品推荐
相关产品推荐

