【超详细】springboot + springdoc-openapi + knife4j 集成案例

简介: springdoc-openapijava库有助于使用 spring boot 项目自动生成 API 文档。 springdoc-openapi通过在运行时检查应用程序以根据 spring 配置、类结构和各种注释推断 API 语义来工作。

springdoc-openapi 简介

springdoc-openapijava库有助于使用 spring boot 项目自动生成 API 文档。 springdoc-openapi通过在运行时检查应用程序以根据 spring 配置、类结构和各种注释推断 API 语义来工作。

自动生成 JSON/YAML 和 HTML 格式 API 的文档。可以使用 swagger-api 注释通过注释来完成此文档。

该库支持:

  • OpenAPI3
  • SpringBoot (v1, v2 and v3)
  • JSR-303, specifically for @NotNull, @Min, @Max, and @Size.
  • Swagger-ui
  • OAuth 2
  • GraalVM 原生镜像

为什么使用 springdoc-openapi

由于之前项目一直使用的是springfox3.0来集成swagger管理API接口文档,但目前springfox已经停止维护了。最近在升级底层框架时看到spring官方推荐使用springdoc,在自己一步一步查找相关资料时,发现国内对于这块的参考资料较少,也不全面。故写此篇文章来帮助大家快速集成。

Knife4j简介

Knife4j是一个集Swagger2和OpenAPI3为一体的增强解决方案。

开始集成

Maven引入

首先在maven里引入springdoc-openapi:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.6.15</version>
</dependency>
复制代码

注释的区别

这里需要注意,我们要用swagger3注释替换swagger2注释(它已经包含在springdoc-openapi-ui依赖项中)。swagger 3 注释的包是
io.swagger.v3.oas.annotations:

@Api -> @Tag
@ApiIgnore -> @Parameter(hidden = true) 或 @Operation(hidden = true) 或 @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")
复制代码

以下举几个简单的:

Controller:

@Tag(name = "用户接口")
@RestController
@RequestMapping("sys/user")
public class SysUserController {
    @Resource
    private ISysUserService sysUserService;
    @Operation(summary = "分页查询")
    @GetMapping("page")
    public AjaxResult queryPage(@ParameterObject SysUserPageDTO dto) {
        PageInfo page = sysUserService.queryPage(dto);
        return AjaxResult.success(page);
    }
    @Operation(summary = "详情")
    @GetMapping("{id}")
    public AjaxResult queryInfo(@PathVariable Long id) {
        SysUserDTO dto = sysUserService.queryById(id);
        return AjaxResult.success(dto);
    }
    @Operation(summary = "新增")
    @PostMapping
    public AjaxResult save(@RequestBody SysUserDTO dto) {
        Long id = sysUserService.saveInfo(dto);
        return AjaxResult.success(id);
    }
}
复制代码

POST请求的DTO:

@Schema(description = "用户 数据传输对象")
@Data
@Accessors(chain = true)
public class SysUserDTO implements Serializable {
    @Schema(description = "ID")
    private Long id;
    @Schema(description = "用户名")
    private String userName;
    @Schema(description = "真实姓名")
    private String realName;
    @Schema(description = "密码")
    private String password;
    @Schema(description = "性别(0男,1女)")
    private Integer sex;
    @Schema(description = "电话号码")
    private String phone;
    @Schema(description = "状态(0停用,1正常)")
    private Integer status;
}
复制代码

❗ 如果你使用一个对象来封装你GET请求的参数,会将你的参数封装为一个json,这不是我们想要的:

要解决这样的问题,有两种解决方法(感谢@nano发现及解决的问题):

方法一(推荐):

在官方文档里有这么一句话:“如果您使用一个对象来捕获多个请求查询参数,请注释该方法参数 @ParameterObject”。所以你应该在你get请求封装的对象前加注解 @ParameterObject,同时应该在对象里的参数注解使用 @Parameter,而不是 @Scheme。

GET接口:

@Operation(summary = "分页查询")
@GetMapping("page")
public AjaxResult queryPage(@ParameterObject SysUserPageDTO dto) {
    PageInfo page = sysUserService.queryPage(dto);
    return AjaxResult.success(page);
}
复制代码

GET请求封装的DTO:

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class SysUserPageDTO extends BasePageDTO {
    @Parameter(description = "用户名")
    private String username;
}
复制代码

方法二(不推荐):

添加配置(添加此配置后,就不需要添加额外的@ParameterObject和@Parameter注解):

❗ 注:这个配置在最新版(1.6.15)有个bug,当你使用这个配置以后再用@Valid注解,配置会失效,待官方解决,所以推荐方法一(PS:官方已修复了该问题,下个版本应该会解决)。

spring-doc:
    default-flat-param-object: true
复制代码

配置

配置文件,更多配置请看:springdoc 核心配置

springdoc:
  api-docs:
    # 是否开启接口文档
    enabled: true
  swagger-ui:
    # 持久化认证数据,如果设置为 true,它会保留授权数据并且不会在浏览器关闭/刷新时丢失
    persistAuthorization: true
复制代码

配置文档:

❗ 这里我更推荐将文档标题、作者等信息写到application里,然后通过@ConfigurationProperties引入,会更优雅

@Configuration
@AutoConfigureBefore(SpringDocConfiguration.class)
public class OpenApiConfig {
    private static final String TOKEN_HEADER = "Authorization";
    @Bean
    public OpenAPI openApi() {
        return new OpenAPI()
                .components(
                        new Components().addSecuritySchemes(TOKEN_HEADER,
                                new SecurityScheme()
                                        .type(SecurityScheme.Type.APIKEY)
                                        // 这里配置 bearer 后,你的请求里会自动在 token 前加上 Bearer
                                        .scheme("bearer")
                                        .bearerFormat("JWT")
                        ).addParameters(TOKEN_HEADER,
                                new Parameter()
                                        .in("header")
                                        .schema(new StringSchema())
                                        .name(tokenHeader)
                        ))
                .info(
                        new Info()
                                .title("文档标题")
                                .description("文档描述")
                                .contact(new Contact().name("作者").email("邮箱").url("可以写你的博客地址或不填"))
                                // 参考 Apache 2.0 许可及地址,你可以不配此项
                                .license(new License().name("Apache 2.0").url("https://www.apache.org/licenses/LICENSE-2.0.html"))
                                .version("0.1")
                )
                // 引入外部的文档,我这里引得是 springdoc 官方文档地址,你可以不配此项
                .externalDocs(new ExternalDocumentation()
                        .description("SpringDoc Full Documentation")
                        .url("https://springdoc.org/")
                );
    }
    /**
     * GroupedOpenApi 是对接口文档分组,类似于 swagger 的 Docket
     * 
     * @return
     */
    @Bean
    public GroupedOpenApi authApi() {
        return GroupedOpenApi.builder()
                // 组名
                .group("认证接口")
                // 扫描的路径,支持通配符
                .pathsToMatch("/login")
                // 扫描的包
                .packagesToScan("com.demo.controller.auth")
                .build();
    }
    @Bean
    public GroupedOpenApi sysApi() {
        return GroupedOpenApi.builder()
                .group("系统接口")
                .pathsToMatch("/sys/**")
                // 添加自定义配置,这里添加了一个用户认证的 header,否则 knife4j 里会没有 header
                .addOperationCustomizer((operation, handlerMethod) -> operation.security(
                        Collections.singletonList(new SecurityRequirement().addList(TOKEN_HEADER)))
                )
                .build();
    }
}
复制代码

访问文档

配置完成之后,就可以访问文档地址:http://localhost:${port}/${context-path}/swagger-ui/html.index

❗ 如果你加入了拦截器或引入了spring-security等权限框架,需要放通文档地址及静态资源:

- /**/*.html
- /**/*.css
- /**/*.js
- /**/api-docs/**
复制代码

至此一个简单的接口文档就生成了,是不是很简单

集成knife4j

Maven引入

在maven里引入knife4j

❗ 在knife4j@4.1.0里已经引入了springfox-openapi-ui@1.6.15,注意jar包冲突。

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>
复制代码

❗ 如果你使用的是SpringBoot3,需要注意:

  • Spring Boot 3 只支持OpenAPI3规范
  • Knife4j提供的starter已经引用springdoc-openapi的jar,开发者需注意避免jar包冲突
  • JDK版本必须 >= 17

而且需要引入这个包:

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.0.0</version>
</dependency>
复制代码

访问文档地址

然后你就可以直接访问文档地址了:http://localhost:${port}/${context-path}/doc.html

至此我们就集成完了,有其他疑问欢迎在评论区提出来

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
1月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
13天前
|
JSON JavaScript 前端开发
springboot中使用knife4j访问接口文档的一系列问题
本文介绍了在Spring Boot项目中使用Knife4j访问接口文档时遇到的一系列问题及其解决方案。作者首先介绍了自己是一名自学前端的大一学生,熟悉JavaScript和Vue,正在向全栈方向发展。接着详细说明了如何解决Swagger请求404错误,包括升级Knife4j依赖、替换Swagger 2注解为Swagger 3注解以及修改配置类中的代码。最后,针对报JS错误的问题,提供了删除消息转换器代码的解决方法。希望这些内容能对读者有所帮助。
|
12天前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
47 1
|
19天前
|
存储 Java 调度
Sppring集成Quartz简单案例详解 包括(添加、停止、恢复、删除任务、获取下次执行时间等)
Sppring集成Quartz简单案例详解 包括(添加、停止、恢复、删除任务、获取下次执行时间等)
21 2
|
22天前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
24 1
|
12天前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
34 0
|
1月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
92 1
|
1月前
|
存储 前端开发 Java
Spring Boot 集成 MinIO 与 KKFile 实现文件预览功能
本文详细介绍如何在Spring Boot项目中集成MinIO对象存储系统与KKFileView文件预览工具,实现文件上传及在线预览功能。首先搭建MinIO服务器,并在Spring Boot中配置MinIO SDK进行文件管理;接着通过KKFileView提供文件预览服务,最终实现文档管理系统的高效文件处理能力。
271 11
|
2月前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
|
2月前
|
Java Spring
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
本文介绍了如何在Spring Boot项目中集成Swagger 2.x和3.0版本,并提供了解决Swagger在Spring Boot中启动失败问题“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerEx”的方法,包括配置yml文件和Spring Boot版本的降级。
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决