一、背景
对于spring boot项目的API文档,基本上是使用Swagger来管理接口文档,也就是SpringFox提供的Swagger库,但是已经有接近两年没出新版本。最近项目升级SpringBoot 2.7.2 版本,这个库的兼容就不太合适啦,其实SpringBoot 2.6.x 版本已经不太能兼容,甚至SpringFox 对 SpringBoot3.0 完全不适配,要使用必须降低 SpringBoot的版本。而spring boot提供另一款Swagger库SpringDoc,运用在项目中可简化 API 文档的生成和维护。接下来记录一下SpringBoot整合SpringDoc吧。
二、介绍一下SpringDoc
SpringDoc是一款可以结合SpringBoot使用的API文档生成工具,基于OpenAPI 3,更新发版效率不错,是一款更好用的Swagger库,功能强大,是SpringDoc不仅支持Spring WebMVC项目,还可以支持Spring WebFlux项目,甚至Spring Rest和Spring Native项目等都可以用。SpringDoc注解的使用,是基于OpenAPI 3和Swagger 3的现代化解决方案,相较于旧版的Swagger2(SpringFox),SpringDoc提供了更简洁、更直观的注解方式。springdoc的注解其实是Swagger3的注解,下面是Swagger2与Swagger注解的对应关系如下:
Swagger2 (SpringFox) | Swagger3 (SpringDoc) |
---|---|
@Api | @Tag or @Tags |
@ApiIgnore | @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden |
@ApiImplicitParam | @Parameter |
@ApiImplicitParams | @Parameters |
@ApiModel | @Schema |
@ApiModelProperty(hidden = true) | @Schema(accessMode = READ_ONLY) |
@ApiModelProperty | @Schema |
@ApiOperation(value = “foo”, notes = “bar”) | @Operation(summary = “foo”, description = “bar”) |
@ApiParam | @Parameter |
@ApiResponse(code = 404, message = “foo”) | @ApiResponse(responseCode = “404”, description = “foo”) |
三、集成与使用
在pom.xml中添加它的依赖:
spring boot 2.7.2配置如下:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
而Spring Boot 3.x 要求使用 springdoc-openapi version 2 及以上:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
<!-- 生成 API 接口文档的组件 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
ps:Spring Boot 3配置SpringDoc见下面第四章《SpringBoot3配置SpringDoc》
接下来在application.yml中添加应用配置
# 服务端口
server:
port: 8096
springdoc:
swagger-ui:
# Swagger UI访问路径
path: /swagger-ui.html
# 开启Swagger UI界面
enabled: true
api-docs:
# 修改api-docs路径
path: /v3/api-docs
# 开启api-docs
enabled: true
packages-to-scan: com.springboot.study.controller # 扫描的controller包
# 配置需要生成接口文档的接口路径
paths-to-match: /ftp/**,/admin/**
然后,新建一个配置类SwaggerConfig.java
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.Parameter;
import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.web.method.HandlerMethod;
/**
* @describe: swagger配置
* @author: 容若
* @created: 2024-06-24 10:25
*/
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI springBootAPI() {
return new OpenAPI()
.info(new Info().title("SpringBoot2.7.2 Study API")
.description("springboot2.7.2-ai")
.version("v0.0.1")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("SpringShop Wiki Documentation")
.url("https://springshop.wiki.github.org/docs"));
}
@Bean
public OperationCustomizer customGlobalHeaders() {
/**
* 设置全局请求头参数
*/
return (Operation operation, HandlerMethod handlerMethod) -> {
Parameter token = new Parameter()
.in(ParameterIn.HEADER.toString())
.schema(new StringSchema())
.name("sessionid")
.description("sessionid")
.required(true);
operation.addParametersItem(token);
return operation;
};
}
@Bean
public GroupedOpenApi publicApi() {
/**
* 设置ftp功能分组
*/
return GroupedOpenApi.builder()
.group("ftp")
.pathsToMatch("/ftp/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
/**
* 设置admin分组
*/
return GroupedOpenApi.builder()
.group("admin")
.pathsToMatch("/admin/**")
.build();
}
}
最后,在所需生成API文档的Controller类中加入注解
package com.springboot.study.controller;
import com.swsc.ai.common.Result;
import com.swsc.ai.entity.request.FtpReqParam;
import com.swsc.ai.service.FtpDownloadFileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @describe: ftp文件下载
* @author: 容若
* @created: 2024-06-20 10:11
*/
@Tag(name = "FtpFileDownloadController", description = "ftp文件下载接口")
@Slf4j
@RestController
@RequestMapping("/ftp")
public class FtpFileDownloadController {
@Autowired
private FtpDownloadFileService ftpDownloadFileService;
@PostMapping("/start/download-file")
@Operation(summary = "ftp文件下载", description = "ftp下载请求")
public Result<String> downloadFtpFile(@RequestBody FtpReqParam reqParam) {
log.info("ftp下载请求:{}", reqParam.getReqToken());
return Result.result(() -> ftpDownloadFileService.downloadFtpFile(reqParam));
}
}
运行项目成功后,访问:
http://localhost:8096/swagger-ui.html
最终会重定向到
http://localhost:8096/swagger-ui/index.html
结果如图:
四、SpringBoot3配置SpringDoc
1.SpringBoot3配置Knife4j
Knife4j 是一个集 Swagger2 和 OpenAPI3 为一体的增强解决方案。Knife4j 相当于是对 SpringDoc UI 优化的一个组件。Knife4j就是一个接口文档工具,可以看作是Swagger的升级版,但是界面比Swagger更好看,功能更丰富。上面步骤已经引入依赖。
<!-- 生成 API 接口文档的组件 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
2.添加配置项
server.port: 8800 # 设置端口号
server:
servlet:
context-path: /test # 设置服务器的访问路径
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: test
paths-to-match: '/**'
# 生成文档所需的扫包路径,一般为启动类目录
packages-to-scan: com.gdb.test
#knife4j 增强配置
knife4j:
#是否启用增强设置
enable: true
#开启生产环境屏蔽
production: false
#是否启用登录认证
basic:
enable: true
username: admin
password: 123456
setting: # 前端UI的个性化配置属性
language: zh_cn # 显示语言中文
enable-version: true
enable-swagger-models: true # 是否显示界面中SwaggerModel功能
swagger-model-name: SwaggerModel2 # 重命名SwaggerModel名称,默认
enable-document-manage: true # 是否显示界面中"文档管理"功能
3.设置文档首页
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI myOpenAPI() {
return new OpenAPI()
// 接口文档标题
.info(new Info().title("程序员API")
// 接口文档简介
.description("这是基于Knife4j OpenApi3的接口文档")
.termsOfService("https://blog.csdn.net/weixin_65032328?type=blog")
// 接口文档版本
.version("v1.0.0")
// 接口文档协议
.license(new License()
.name("许可协议")
.url("https://blog.csdn.net/weixin_65032328?type=blog"))
// 开发者联系方式
.contact(new Contact()
.name("迷人的小宝")
.email("dingbaogui8@gmail.com")
.url("https://blog.csdn.net/weixin_65032328?type=blog")))
.externalDocs(new ExternalDocumentation()
.description("小宝945博客")
.url("https://blog.csdn.net/weixin_65032328?type=blog"));
}
}
4.编写控制器
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "项目首页", description = "用户首先访问的页面")
@RestController
public class HelloController {
@Parameters ({ //详细说明每一个参数
@Parameter(name = "name", description = "请求人姓名", required = true)
})
@Operation (summary = "简短描述", description = "更详细的描述")
@PostMapping("/calldingbao")
public String hello(String name){
return name + "好啊,我是xiu宝哦!!!";
}
}
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户数据增删改查")
public class UserController {
@Operation(
summary = "根据ID,查询用户",
parameters = {
@Parameter(name = "id", description = "用户的唯一标识 id", required = true, in = ParameterIn.PATH)
},
responses = {
@ApiResponse(responseCode = "200", description = "成功", content = @Content(mediaType = "application/json")),
@ApiResponse(responseCode = "400", description = "错误", content = @Content(mediaType = "application/json"))
}
)
@GetMapping("/{id}")
public Integer getUserById(@PathVariable int id) {
return id;
}
}
5.文档展示
运行项目,访问:http://127.0.0.1:8080/test/doc.html