Swagger 文档
Swagger 集成基于 springdoc-openapi 做了一层扩展,并捆绑 knife4j-openapi3-ui 提供独立的中文风格 UI;重点解决 Spring Data 分页 / 排序与 Querydsl Predicate 在 OpenAPI 文档中难以自动呈现的问题。
主要扩展
- 双 UI 共存:springdoc 原生
swagger-ui+ knife4jdoc.html,按需启用 - Pageable / Sort 参数自动生成:避免手写
@Parameter描述分页/排序参数 - Querydsl Predicate 参数自动生成:把
@QuerydslPredicate绑定的字段展开成 OpenAPI 参数 - 按需装配:相关扩展按 classpath 与上下文条件装配,不引入额外硬依赖
安装
Maven
<dependency>
<groupId>com.jeeapp.spring.boot</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</dependency>
Gradle
implementation 'com.jeeapp.spring.boot:swagger-spring-boot-starter'
配置
# 启用 springdoc 原生 swagger-ui(与 knife4j doc.html 可同时存在)
springdoc.swagger-ui.enabled=true
# 让 swagger-ui 通过应用根路径访问
springdoc.swagger-ui.use-root-path=true
# 关闭右上角的 Petstore 默认 URL,避免误导
springdoc.swagger-ui.disable-swagger-default-url=true
# 接口列表按 HTTP 方法(GET/POST/...)排序
springdoc.swagger-ui.operations-sorter=method
关键说明:
springdoc.swagger-ui.enabled:springdoc 原生 UI 入口,默认地址/swagger-ui.html。- knife4j UI:始终通过
/doc.html暴露;如果通过springdoc.api-docs.enabled=false关闭了 springdoc 原生路由,本 Starter 会自动接管doc.html的资源映射,仍可访问 knife4j。
扩展能力
双 UI 共存
- 默认依赖:
springdoc-openapi-ui+knife4j-openapi3-ui。 - 默认入口:springdoc
/swagger-ui.html、knife4j/doc.html。 - 当
springdoc.api-docs.enabled=false时,SwaggerAutoConfiguration.Knife4jUiWebMvcConfiguration通过WebMvcConfigurer#addResourceHandlers显式注册doc.html资源,确保 knife4j UI 仍可访问。
Pageable / Sort 参数自动生成
com.jeeapp.swagger.customizers.PageableOperationCustomizer 是一个 GlobalOperationCustomizer:
- 当 Controller 方法形参出现
org.springframework.data.domain.Pageable,自动追加page/size/sort三个 query 参数(sort为字符串数组)。 - 当形参出现
org.springframework.data.domain.Sort,仅追加sort数组参数。 - 静态初始化中通过
SpringDocUtils.getConfig()把@PageableDefault与@SortDefault加入忽略注解列表,避免它们被错误展开为请求体或参数。
按需装配:仅当 classpath 存在 Pageable 时由 PageableProvider 注册。
示例:
@GetMapping("/users")
public Page<User> list(Pageable pageable) {
// OpenAPI 自动生成 page / size / sort 参数
return userRepository.findAll(pageable);
}
Querydsl Predicate 参数自动生成
com.jeeapp.swagger.customizers.QuerydslPredicateOperationCustomizer 解析方法形参上的 @QuerydslPredicate:
- 反射读取
QuerydslBindings内部的pathSpecs/denyList(blackList) /allowList(whiteList) /aliases/excludeUnlistedProperties,决定最终展开哪些字段。 - 通过
ModelConverters解析每个字段的 Schema,无法解析时回退为string。 - 把展开后的字段以独立 query
Parameter形式追加到 Operation。 - 通过
SpringDocUtils.addRequestWrapperToIgnore(Predicate.class)防止Predicate被误识别为请求体包装类。
按需装配:仅当 classpath 存在 QuerydslBindingsFactory 时由 QuerydslProvider 注册(@Lazy(false) 强制启动期完成 wrapper-ignore 注册)。
示例:
@GetMapping("/users")
public Page<User> list(@QuerydslPredicate(root = User.class) Predicate predicate, Pageable pageable) {
// 自动展开 User 上的可绑定字段为 query 参数
return userRepository.findAll(predicate, pageable);
}