文章介绍了如何在SpringDoc中添加排序规则以解决API标签排序问题,同时回顾了从Swagger2到OpenAPI3的变迁,提到了Springfox和Springdoc的区别。此外,文章还探讨了Knife4j作为增强SwaggerUI的解决方案,以及它与Springdoc的集成和使用情况。最后,文章讨论了Springdoc的排序配置及其对不同页面的影响。
摘要生成于
,由 DeepSeek-R1 满血版支持,
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Comparator;
import java.util.stream.Collectors;
@OpenAPIDefinition(
security = @SecurityRequirement(name = "Authorization")
@SecurityScheme(type = SecuritySchemeType.APIKEY, name = "Authorization", scheme = "Authorization", in = SecuritySchemeIn.HEADER)
@Configuration
public class OpenApiConfig {
private String title = "SpringDoc API";
private String description = "SpringDoc Application";
private String version = "v0.0.1";
@Bean
public OpenAPI springOpenAPI() {
return new OpenAPI()
.info(new Info()
.title(title)
.description(description)
.version(version));
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group(title)
.pathsToMatch("/**")
.addOpenApiCustomiser(sortTagsAlphabetically())
.build();
public OpenApiCustomiser sortTagsAlphabetically() {
return openApi -> openApi.setTags(openApi.getTags()
.stream()
.sorted(Comparator.comparing(tag -> StringUtils.stripAccents(tag.getName())))
.collect(Collectors.toList()));
其他方法:如果你的项目可以升级,可以参考knife4j 的官方Issues 中的解决办法https://gitee.com/xiaoym/knife4j/issues/I5Z1YP
二、回顾历史
之前项目里一直用的都是
springfox+
knife4j
来实现自动生成在线接口文档的,基本pom坐标如下:
<!-- Swagger2 核心依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<!-- Swagger2 ui页面 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<!--配合Swagger2 形成一个knife4j页面 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
基本可以看出来,用的是swagger2
最新有个项目改成了springdoc +knife4j-springdoc-ui 的形式。项目集成pom坐标如下:
<!--swagger-->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.8</version>
</dependency>
<!--注意用的是 knife4j-springdoc-ui-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-springdoc-ui</artifactId>
<version>3.0.3</version>
</dependency>
关于knife4j-springdoc-ui 属于纯UI,没有之前用knife4j的一些增强功能,作者在gitee上对其进行了说明https://gitee.com/xiaoym/knife4j/issues/I4J6R7
当然如果很看好knife4j这款ui界面,可以直接集成knife4j-openapi3-jakarta-spring-boot-starter,是支持OpenAPI 3规范的,因为knife4j-springdoc-ui从做的gitee上来看,更多像是一个过渡产品
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
三、简介knife4j
作者在自己的代码仓库介绍到:knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍knife4j的前身是swagger-bootstrap-ui,为了契合微服务的架构发展,由于原来swagger-bootstrap-ui采用的是后端Java代码+前端Ui混合打包的方式,在微服务架构下显的很臃肿,因此项目正式更名为knife4j
当然,我在swagger-bootstrap-ui就开始用了,一直觉得还不错,从最初觉得swagger-ui 的页面丑爆了,到因为这个UI页面慢慢接受了swagger项目地址https://gitee.com/xiaoym/knife4j
四、swagger2和swagger3
OpenAPI 3.0.0 是 OpenAPI 规范的第一个正式版本,因为它是由 SmartBear Software 捐赠给 OpenAPI Initiative,并在2015年从 Swagger 规范重命名为 OpenAPI 规范。
OpenAPI 规范 (中文版)地址:https://openapi.apifox.cn/
swagger 是一个 api 文档维护组织,后来成为了 Open API 标准的主要定义者,现在最新的版本为17年发布的 Swagger3(Open Api3)。
swagger2于17年停止维护,现在最新的版本为 Swagger3(Open Api3)。
swagger2 遵循的是 OpenAPI 2 规范
swagger3 遵循的是 OpenAPI 3 规范
springfox 和 Springdoc
-
SpringFox是 spring 社区维护的一个项目(非官方),一般集成swagger2 用的多
-
SpringDoc也是 spring 社区维护的一个项目(非官方),集成swagger3 用的多
SpringDoc支持swagger页面Oauth2登录(Open API3的内容),相较 SpringFox来说,它的支撑时间更长,无疑是更好的选择。但由于国内发展较慢,在国内不容易看到太多有用的文档,不过可以访问它的官网。它的使用了 swagger3(OpenAPI3),但
swagger3 并未对 swagger2 的注解做兼容,不易迁移
,也因此,
名气并不如 spring fox。
SpringFox
|
SpringDoc
|
@Api
|
@Tag
|
@Apilgnore
|
@Parameter(hidden = truelor@Operation(hidden = true)or@Hidden
|
@ApilmplicitParam
|
@Parameter
|
@ApilmplicitParams
|
@Parameters
|
@ApiModel
|
@Schema
|
@ApiModelProperty
|
@Schema
|
@ApiOperation(value = "foo", notes = "bar")
|
@Operation(summary = "foo", description ="bar")
|
@ApiParam
|
@Parameter
|
@ApiResponse(code = 404.message = "foo")
|
@ApiResponse(responseCode ="404", description = "foo")
|
五、解读Springdoc
官网地址:https://springdoc.org/
springdoc-openapi 其实就是swagger3 ,是swagger团队在将swagger 将其作品捐献给开源的啥来着,后来就改名叫这个springdoc了
SpringDoc是一款可以结合SpringBoot使用API文档生成工具,基于OpenAPI 3,而且项目维护和社区都在不断更新,不仅支持SpringMVC,而且还支持Spring WebFlux项目。
官网架构图如下,可以清晰的认知springdoc-openapi-ui 所在的层级
如果没有用到knife4j ,单纯的springdoc-openapi 的UI页面查看接口,那就更简单了直接修改配置文件,添加排序方法,但是这个排序对于knife4j 是不起作用的,因为是个前端js排序,只对http://localhost:8080/swagger-ui/index.html生效。
对于http://localhost:8080/doc.html暂时只能在java 端排序好进行返回,后面会具体分析
springdoc:
api-docs:
#是否开启文档功能,默认为true,可不配置
enabled: true
swagger-ui:
# 访问ip:host/api,可直接访问Swagger springdoc
path: /api
# API 排序
tags-sorter: alpha
# HTTP 方法排序
operations-sorter: method
不重写排序返回的分组是随机的
配置swagger-ui 的tags-sorter是前台排序,访问http://localhost:8080/swagger-ui/index.html
查看网络请求返回数据:会看到我们在yml里面配置好的排序规则
查看排序规则,会发现返回的tags 顺序和实际页面显示的顺序并不一致,因为我们在配置文件设置的tags-sorter生效了
来证明对于knife4j 无效,访问
http://localhost:8080/doc.html
,可以发现页面排序完全和返回tags一致
对http://localhost:8080/swagger-ui/index.html 进行F12 查看网页源代码,可知这里调用了js 的字符串排序方法
参考官方文档 https://springdoc.org 的 5.2 swagger-ui properties 可知,有以下2个配置项可供我们给 API 和 HTTP 方法排序:
-
springdoc.swagger-ui.tagsSorter 给 API 排序, 如果其值为 alpha 就表示按字母顺序排序。默认情况下(也就是不配置此项),API 的顺序由 swagger 自己决定(也就是没什么顺序);
-
springdoc.swagger-ui.operationsSorter 给 HTTP 方法排序,其值为 alpha 同样表示按字母顺序排序,值为 method 表示根据 HTTP 请求的类型(顺序如下:DELETE > GET > POST > PUT)排序。默认情况下,Controller 代码里面,你写的是什么顺序,swagger 就给你展示什么顺序。
翻译过来就是:对每个API的标记列表应用排序。它可以是‘’alpha'(按字母数字路径排序)或函数(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort,了解如何编写排序函数)。每次传递都将两个标记名字符串传递给排序器。默认值是由Swagger UI确定的顺序。
针对springdoc 页面上的Authorize 不生效问题
@Bean
public OpenAPI mallTinyOpenAPI() {
// 作者信息
final Contact contact = new Contact();
contact.setName(company.getCompanyName());
contact.setUrl(company.getCompanyWebsite());
contact.setEmail(company.getCompanyEmail());
// 鉴权组件
final SecurityScheme securityScheme = new SecurityScheme().type(SecurityScheme.Type.APIKEY).scheme("bearer")
.bearerFormat("JWT").in(SecurityScheme.In.HEADER).name(SpringDocConfig.TOKEN_KEY);
final Components components = new Components().addSecuritySchemes(SpringDocConfig.TOKEN_KEY, securityScheme);
return new OpenAPI()
.info(new Info().title(systemConfig.getSysName() + "接口文档").description(systemConfig.getSysName())
.version("v1.0.0").contact(contact))
//配置这个只能对springdoc生效 http://localhost:8410/supplies/swagger-ui/index.html
.addSecurityItem(new SecurityRequirement().addList(SpringDocConfig.TOKEN_KEY))
.components(components)
knef4j 配置
@Bean
public GroupedOpenApi allSpringDocApi() {
List<SecurityRequirement> securityRequirements = new ArrayList<>();
securityRequirements.add(new SecurityRequirement().addList(SpringDocConfig.TOKEN_KEY));
return GroupedOpenApi.builder().group("全部接口").pathsToMatch("/api/**")
.addOperationCustomizer((operation, handlerMethod) -> {
return operation.security(securityRequirements);
}).addOpenApiCustomiser(sortTagsAlphabetically()).build();
// 增加排序功能
public OpenApiCustomiser sortTagsAlphabetically() {
return openApi -> openApi.setTags(
openApi.getTags().stream().sorted(Comparator.comparing(tag ->
StringUtils.stripAccents(tag.getName())))
.collect(Collectors.toList()));
Knife4j前身是swagger-bootstrap-ui,是一个为Swagger接口文档赋能的工具
文档:https://xiaoym.gitee.io/knife4j/(opens new window)
效果(旧版):http://swagger-bootstrap-ui.xiaominfo.com/doc.html(opens new window)
效果(2.X版):http://knife4j.xiaominfo.com/doc.html(opens new window)
Gitee
效果(旧版):http://swagger-bootstrap-ui.xiaominfo.com/doc.html
效果(2.X版):http://knife4j.xiaominfo.com/doc.html
Gitee:https://gitee.com/xiaoym/knife4j
GitHub:https://github.com/
Swagger现在已经成了最流行的接口文档生成与管理工具,但是你是否在用的时候也在吐槽,它是真的不好看,接口测试的json数据没法格式化,测试地址如果更改了还要去改配置,接口测试时增加token验证是真的麻烦......等等,拿什么拯救你,swagger同学!
针对Swagger的种种缺点,Knife4j就呼之欲出了。
在Springboot整合Swagger时,想要使用官方的swagger-ui来实现文档中的接口排序并没有找到方法。所以使用了swagger-bootstrap-ui来实现该功能,swagger-bootstrap-ui能够实现Swagger-UI的增强。其中就有实现文档中接口排序的功能。其他功能请看swagger-bootstrap-ui开发指南
下面介绍实现步骤:
先引入swagger和swag
回答: Knife4j 是 swagger-bootstrap-ui 的改进版本,它是 springfox-swagger-ui 的增强 UI 实现。相比于 swagger-bootstrap-ui,Knife4j 更加小巧、轻量,并且功能更加强大。swagger-bootstrap-ui 采用的是前端 UI 混合后端 Java 代码的打包方式,在微服务的场景下显得较为臃肿。而 Knife4j 则更加轻量,功能更加强大。此外,如果项目中之前使用过 Swagger 生成接口文档,切换到 Knife4j 是非常顺畅的,只需要在 pom.xml 文件中将 springfox-boot-starter 替换为 knife4j-spring-boot-starter,并将访问地址从原来的 http://${host}:${port}/swagger-ui.html 切换到 http://${host}:${port}/doc.html。如果项目中加了权限认证,还需要给 Knife4j 添加白名单。[1][2][3]