优雅哥 SpringBoot 2.7.2 实战基础 - 04 -集成 Spring Doc 接口文档和 knife4j

前面已经集成 MyBatis Plus、Druid 数据源,开发了 5 个接口。在测试这 5 个接口时使用了 HTTP Client 或 PostMan,无论是啥都比较麻烦:得自己写请求地址 URL、请求参数等,于是多年前就出现了 Swagger 这个玩意。Swagger 可以自动生成接口文档,还能很方便的测试各个接口。但不幸的是,MVN Repository 上面 Springfox Swagger2 的版本停止于 2020 年 7月,而写下这篇文章是 2022 年 8 月,已经两年过去没有动静了,与此同时,springdoc-openapi 悄然出现。

spring doc open api 支持 Open API 3、Swagger-ui等,可以很方便与 Spring Boot 整合,配置和使用与 Springfox Swagger2 类似。

1 集成 Spring Doc

1.1 添加依赖

springdoc-openapi 不是 Spring Framework 官方团队开发的,而是社区项目,没有包含在 spring-boot-dependencies 中。故需要先定义版本号:

<properties>
....
<springdoc-openapi-ui.version>1.6.9</springdoc-openapi-ui.version>
</properties>

添加依赖:

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc-openapi-ui.version}</version>
</dependency>

该依赖里面使用了 swagger-ui,以HTML形式展示文档。

1.2 编写配置类

其实配置类写不写都可以,如果不写配置类,就通过注解定义文档信息就可以。创建类:com.yygnb.demo.config.SpringDocConfig

package com.yygnb.demo.config;

import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class SpringDocConfig { private String title = "Hero SpringBoot Demo";
private String description = "Hero Demo for usage of Spring Boot";
private String version = "v0.0.1";
private String websiteName = "Hero Website";
private String websiteUrl = "http://www.yygnb.com"; @Bean
public OpenAPI heroOpenAPI() {
return new OpenAPI()
.info(new Info().title(title)
.description(description)
.version(version))
.externalDocs(new ExternalDocumentation().description(websiteName)
.url(websiteUrl));
}
}

上面的配置定义了展示的文档的信息,与界面上对应关系如下:

在配置文件中除了可以配置文档的信息,还可以配置文档分组、Authorization 等,在后面的企业级实战文章中会具体描写,将会在网关层 spring cloud gateway 中集成所有微服务的接口。

1.3 配置yml

在 application.yml 配置 springdoc:

# 接口文档
springdoc:
packages-to-scan: com.yygnb.demo.controller
swagger-ui:
enabled: true

这两项不配置也可以,packages-to-scan 默认为启动类所在的路径;springdoc.swagger-ui.enabled 默认为true,配置后可以在不同的环境中开启或关闭。

1.4 添加注解

springdoc-openapi 与 springfox-swagger2 提供的注解有很大差别:

swagger 2 spring doc 描述
@Api @Tag 修饰 controller 类,类的说明
@ApiOperation @Operation 修饰 controller 中的接口方法,接口的说明
@ApiModel @Schema 修饰实体类,该实体的说明
@ApiModelProperty @Schema 修饰实体类的属性,实体类中属性的说明
@ApiImplicitParams @Parameters 接口参数集合
@ApiImplicitParam @Parameter 接口参数
@ApiParam @Parameter 接口参数

修改实体类 Computer,添加 springdoc-openapi 注解:

@Schema(title = "电脑")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Computer implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO)
private Long id; @Schema(title = "尺寸")
private BigDecimal size; @Schema(title = "操作系统")
private String operation; @Schema(title = "年份")
private String year;
}

修改控制器 ComputerController,添加注解:

@Tag(name = "电脑相关接口")
@RequiredArgsConstructor
@RestController
@RequestMapping("/computer")
public class ComputerController { private final IComputerService computerService; @Operation(summary = "根据id查询电脑")
@GetMapping("/{id}")
public Computer findById(
@Parameter(name = "id", required = true, description = "电脑id") @PathVariable Long id) {
return this.computerService.getById(id);
} @Operation(summary = "分页查询电脑列表")
@Parameters(value = {
@Parameter(name = "page", description = "页面,从1开始", example = "2"),
@Parameter(name = "size", description = "每页大小", example = "10")
})
@GetMapping("/find-page/{page}/{size}")
public Page<Computer> findPage(@PathVariable Integer page, @PathVariable Integer size) {
return this.computerService.page(new Page<>(page, size));
} @Operation(summary = "新增电脑")
@PostMapping()
public Computer save(@RequestBody Computer computer) {
computer.setId(null);
this.computerService.save(computer);
return computer;
} @Operation(summary = "根据id修改电脑")
@PutMapping("/{id}")
public Computer update(
@Parameter(name = "id", required = true, description = "电脑id") @PathVariable Long id,
@RequestBody Computer computer) {
computer.setId(id);
this.computerService.updateById(computer);
return computer;
} @Operation(summary = "根据id删除电脑")
@DeleteMapping("/{id}")
@Parameter(name = "id", required = true, description = "电脑id")
public void delete(@PathVariable Long id) {
this.computerService.removeById(id);
}
}

1.5 运行测试

启动服务,在浏览器中访问:

http://localhost:9099/swagger-ui/index.html

2 api-docs

在文档标题下面有一个小链接:/v3/api-docs,点击该链接,会在新页面中显示一大坨 JSON 数据。

看似很无聊的数据,却有着重大意义,swagger-ui 就是通过这些数据渲染出页面的。此外,这些JSON数据在某种程度上可以简化前端的开发及前后端网络请求的工作量。

hero-admin-ui

优雅哥正在开发的基于 Vue 3 + TypeScript 的开源项目 hero-admin-ui,其特色就是基于 JSON Schema 的表单和列表。通过 JSON Schema 可以快速渲染出一个列表、表单,甚至是搜索页和详情表单页。如果独立使用 hero-admin-ui,需要手动编写 JSON Schema,但如果后端接口整合了 Swagger 或 Spring Doc,上面 api-docs 返回的 JSON,就包含了 JSON Schema,二者结合可以快速实现搜索页、表单页等。目前 hero-admin-ui 已发布在 npmjs 上,也已经提交到 github上,大家可以搜索关键字 hero-admin-ui 查看。在后面的实战篇中,前端部分将会使用这个组件库实现前端页面。

3 自定义配置

在 ”1.2 编写配置类“ 一节,文档信息都是写死在代码中的,如果多个微服务都要集成 spring doc,可以把前面写的 SpringDocConfig 提取到公共模块中,通过maven 依赖引用,在 application.yml 中配置不同的变量。

3.1 添加依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

配置该依赖的目的是在编写 application.yml 时,自定义的属性有代码提示。它会生成配置元数据,无需自己手动编写。

3.2 定义配置的实体类

创建 com.yygnb.demo.config.DocInfo,将 SpringDocConfig 中写死的属性都移到这个配置实体类中:

@Data
@Component
@ConfigurationProperties(prefix = "doc-info")
public class DocInfo { private String title = "Demo Title";
private String description = "Demo Description";
private String version = "v0.0.1";
private String websiteName = "Demo Website";
private String websiteUrl = "http://www.yygnb.com";
}

注解 @ConfigurationProperties(prefix = "doc-info") 声明配置属性,在 application.yml 配置时就可以使用 doc-info。

3.3 重构 SpringDocConfig

在 SpringDocConfig 中引入 DocInfo,并通过构造函数进行注入:

@RequiredArgsConstructor
@Configuration
public class SpringDocConfig { private final DocInfo docInfo; @Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info().title(docInfo.getTitle())
.description(docInfo.getDescription())
.version(docInfo.getVersion()))
.externalDocs(new ExternalDocumentation().description(docInfo.getWebsiteName())
.url(docInfo.getWebsiteUrl()));
}
}

补充一个小点:注解 @RequiredArgsConstructor 是 lombok 中提供的,它等价于在类中编写了方法:

public SpringDocConfig(DocInfo docInfo) {
this.docInfo = docInfo;
}

构造注入时,在构造函数中写大量的属性,毫无意义。既然已经使用了 @Data 注解,为啥不用 @RequiredArgsConstructor 呢?

3.4 使用自定义配置

自定义配置已经完成,可以在 application.yml 中使用 DocInfo 对应的配置了:

doc-info:
title: SpringBoot Demo演示
description: 学习 Spring Boot 2.7.2

DocInfo 所有属性都定义了默认值,在 application.yml 可以覆盖默认值,如上面的 titledescription 属性。重启服务查看运行效果:

4 集成 knife4j

在之前 springfox-swagger 的时代,很多同学不喜欢 swagger-ui 的界面风格,会集成 knife4j 的 ui。Spring Doc 也可以集成 knife4j。

如果要使用 knife4j ,Spring Doc 的配置中需要添加分组配置,我们这里添加一个最简单的分组配置。

com.yygnb.demo.config.SpringDocConfig

@RequiredArgsConstructor
@Configuration
public class SpringDocConfig { private final DocInfo docInfo; @Bean
public OpenAPI heroOpenAPI() {
return new OpenAPI()
.info(new Info().title(docInfo.getTitle())
.description(docInfo.getDescription())
.version(docInfo.getVersion()))
.externalDocs(new ExternalDocumentation().description(docInfo.getWebsiteName())
.url(docInfo.getWebsiteUrl()));
} @Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group(docInfo.getTitle())
.pathsToMatch("/**")
.build();
}
}

如果不添加这个 GroupedOpenApi 实例,knife4j ui就显示不出来。

在 pom.xml 中引入 knife4j

<properties>
...
<knife4j-springdoc-ui.version>3.0.3</knife4j-springdoc-ui.version>
</properties> <dependencies>
...
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-springdoc-ui</artifactId>
<version>${knife4j-springdoc-ui.version}</version>
</dependency>
</dependencies>

启动服务,访问:

http://localhost:9099/doc.html

显示 knife4j 的ui:



今日优雅哥(工\/youyacoder)学习结束,期待关注留言分享~~

集成 Spring Doc 接口文档和 knife4j-SpringBoot 2.7.2 实战基础的更多相关文章

  1. Spring Boot 集成 Swagger生成接口文档

    目的: Swagger是什么 Swagger的优点 Swagger的使用 Swagger是什么 官网(https://swagger.io/) Swagger 是一个规范和完整的框架,用于生成.描述. ...

  2. Spring Boot 集成 Swagger 构建接口文档

    在应用开发过程中经常需要对其他应用或者客户端提供 RESTful API 接口,尤其是在版本快速迭代的开发过程中,修改接口的同时还需要同步修改对应的接口文档,这使我们总是做着重复的工作,并且如果忘记修 ...

  3. Springboot集成swagger2生成接口文档

    [转载请注明]: 原文出处:https://www.cnblogs.com/jstarseven/p/11509884.html    作者:jstarseven    码字挺辛苦的.....   一 ...

  4. Springboot系列(七) 集成接口文档swagger,使用,测试

    Springboot 配置接口文档swagger 往期推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配 ...

  5. spring boot使用swagger生成api接口文档

    前言 在之前的文章中,使用mybatis-plus生成了对应的包,在此基础上,我们针对项目的api接口,添加swagger配置和注解,生成swagger接口文档 具体可以查看本站spring boot ...

  6. SpringBoot 如何生成接口文档,老鸟们都这么玩的!

    大家好,我是飘渺. SpringBoot老鸟系列的文章已经写了两篇,每篇的阅读反响都还不错,果然大家还是对SpringBoot比较感兴趣.那今天我们就带来老鸟系列的第三篇:集成Swagger接口文档以 ...

  7. springboot+swagger接口文档企业实践(上)

    目录 1.引言 2.swagger简介 2.1 swagger 介绍 2.2 springfox.swagger与springboot 3. 使用springboot+swagger构建接口文档 3. ...

  8. restful接口文档

    1.先理清业务bai流程 2.定义前后端开发的接口规范.比如json的格dao式,url的格式 3.定内义接口文容档,这里的接口文档一般就是对应后台的实体reqVo(调用后台接口<控制器> ...

  9. SpringCloud微服务实战——搭建企业级开发框架(六):使用knife4j集成Swagger2接口文档

    knife4j是为集成Swagger生成api文档的增强解决方案,前后端Java代码以及前端Ui模块进行分离,在微服务架构下使用更加灵活, 提供专注于Swagger的增强解决方案,不同于只是改善增强前 ...

随机推荐

  1. 好客租房7-React脚手架的使用

    3.3在脚手架中使用React //第一步导入react import React from "React" import ReactDOM from "react-do ...

  2. Sqoop导入数据到mysql数据库报错:ERROR tool.ExportTool: Error during export: Export job failed!(已解决)

    问题描述: Container killed by the ApplicationMaster. Container killed on request. Exit code is 143 Conta ...

  3. OpenHarmony3.1 Release版本特性解析——硬件资源池化架构介绍

    李刚 OpenHarmony 分布式硬件管理 SIG 成员 华为技术有限公司分布式硬件专家 OpenHarmony 作为面向全场景.全连接.全智能时代的分布式操作系统,通过将各类不同终端设备的能力进行 ...

  4. ajax与python后端交互

    目录 ajax简介 前后端传输数据编码格式 ajax发送json格式数据 ajax携带文件数据 回调机制处理策略 ajax简介 ajax可以在页面不刷新的情况下可以与后端进行数据交互,异步提交,局部刷 ...

  5. GO的日志库log竟然这么简单!

    前言 最近在尝试阅读字节开源RPC框架Kitex的源码,看到日志库klog部分,果不其然在Go原生的log库的基础上增加了自己的设计,大体包括增加了一些格式化的输出.增加一些常用的日志级别等. 一番了 ...

  6. Docker打包镜像并上传

    Docker打包镜像并上传 登录 账号 docker login --username=yourusername 密码 yourPassword 推送到仓库 docker镜像打标签 docker ta ...

  7. 一个全新的Vue拖拽特性实现:“移动”部分

    关于拖拽 CabloyJS提供了完备的拖拽特性,可以实现移动和调整尺寸两大类功能,这里对移动的开发进行阐述 关于调整尺寸的开发,请参见:拖拽:调整尺寸 演示 开发步骤 下面以模块test-party为 ...

  8. Wireshark学习笔记(二)取证分析案例详解

    @ 目录 练习一:分析用户FTP操作 练习二:邮件读取 练习三:有人在摸鱼? 练习一:分析用户FTP操作 已知抓包文件中包含了用户登录FTP服务器并进行交互的一个过程,你能否通过wireshark分析 ...

  9. ExtJS 布局-Table布局(Table layout)

    更新记录: 2022年6月1日 开始. 2022年6月10日 发布. 1.说明 table布局类似表格,通过指定行列数实现布局. 2.设置布局方法 在父容器中指定 layout: 'table' la ...

  10. flink 流的合并

    flink 流的合并操作 union union只能合并类型相同的数据,合并的结果仍然是DataStream,结果操作与未合并之前一致. public static void main(String[ ...