背景
集群上部署的服务 contextPath = /serviceName(war包的名字,例如学生账号服务 /student),但是为了区分一个域名下不同的大服务(例如用户服务 /user),需要让访问方式变为:https://域名/user/serviceName,为此在 nginx 进行了 rewrite。
但此时 swagger 上 basePath = /serviceName,每次在 swagger 模拟请求,都要手动去添加 /user,非常不方便。怎么方便地修改 swagger 的 basePath = /user/serviceName ?
调研过的其他方式
1. 修改contextPath。是一个好方法,如果能直接修改contextPath,就不存在上面的问题了,例如我本地用springboot内置tomcat启动,设置了server.servlet.context-path=/user/student,swagger的basePath直接就是正确的。
2. 使用 Controller 做 forward (看起来对代码改动较多,未尝试),参考:springfox-swagger-ui 在二级目录下的路径问题_Javadoop
3. @Api 注解里的 basePath 设置,1.5.X 版本开始已弃用。
我的方式
- 在 swagger 配置里设置 pathProvider 为 RelativePathProvider
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Swagger2Config {
@Autowired
private MyConfig myConfig;
@Bean
public Docket publicRestApi(ServletContext servletContext) {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build()
.groupName("用户系统-学生端使用")
.apiInfo(apiInfo())
;
// 集群上 context-path 不包含 /user,通过 nginx 转发的,swagger需要手动增加路径
// 本地环境内置 tomcat 启动,直接配置 context-path 包含 /user,不需要增加 basePath
if (!myConfig.isLocalMode()) {
docket.pathProvider(new RelativePathProvider(servletContext) {
@Override
public String getApplicationBasePath() {
return "/user" + super.getApplicationBasePath();
}
});
}
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("用户系统接口文档")
.description("供学生使用的服务")
.termsOfServiceUrl("https://my.com/user/student")
.version("1.0")
.build();
}
}
依赖
compile (group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2')
compile (group: 'com.github.xiaoymin', name: 'knife4j-spring-boot-starter', version: '2.0.1')
MyConfig
@Getter
@Setter
@Configuration
public class MyConfig{
@Value("${my-server.testMode}")
private boolean testMode;
}
====================================
2023.03更新,swagger 3.0,swagger-ui访问会404,参考下面这个配置:[Swagger3.0]swagger-ui.html无法访问的解决方案_臧初之的博客-优快云博客