当前位置: 首页 > news >正文

Spring Boot 集成 Knife4j 的 Swagger 文档

在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j 的 Swagger,以实现 API 文档的自动生成和展示。

官网:Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j

源码:knife4j: Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案

1. UI 界面配置步骤

1.1. 添加依赖

<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version>
</dependency>

1.2. 添加配置文件

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {/*** 该方法的主要作用是通过knife4j生成接口文档,若想要多个分组,则需要配置多个Docket实例** @return Docket 实例,用于Swagger接口文档的配置和生成*/@Beanpublic Docket docket(Environment environment) {// 构建API信息,用于Swagger文档的元数据ApiInfo apiInfo = new ApiInfoBuilder().title("swagger测试项目接口文档") // 设置API的标题.contact(new Contact("zjp", "http://termurl.com", "zjp@email.com")).version("1.0") // 设置API的版本.description("swagger测试项目接口文档") // 设置API的描述信息.termsOfServiceUrl("http://termurl.com") // 设置服务条款URL,非必要.license("Apache 2.0") // 设置API的授权协议,非必要.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0") // 设置授权协议的URL,非必要.build();// 创建Docket实例并进行配置Docket docket = new Docket(DocumentationType.SWAGGER_2) // 指定文档类型为Swagger2。支持SWAGGER_12(1.2版本)、SWAGGER_2(2.0版本)、OAS_30(3.0版本)等。多个实例版本不同会在各个版本中各生成一个文档.enable(environment.acceptsProfiles(Profiles.of("dev", "test"))) // 设置是否启用Swagger,默认为true,也可以通过环境变量或配置文件来动态控制.apiInfo(apiInfo) // 设置API信息.select() // 进入配置选择器// 若需要匹配指定包路径的控制器,可以使用basePackage()方法,可以是包名或类名,支持通配符*;// 若需要匹配所有路径,可以使用any()方法,例如:any();// 若需要匹配指定注解的控制器,可以使用withClassAnnotation()方法,例如:withClassAnnotation(RestController.class);// 若需要匹配指定方法注解的控制器,可以使用withMethodAnnotation()方法,例如:withMethodAnnotation(ApiOperation.class);// 若不需要匹配任何注解的控制器,可以使用none()方法,例如:none();.apis(RequestHandlerSelectors.basePackage("com.zjp.knife4jswaggerdemo.controller"))// 若需要匹配指定类,可以使用any()方法,例如:any();// 若需要匹配指定路径,可以使用ant()方法,例如:ant("/api/**");// 若需要排除某些路径,可以使用ant()方法,例如:ant("!/api/**");// 若需要匹配以指定字符串结尾的路径,可以使用ant()方法,例如:ant("/**/api");// 若需要匹配以指定字符串开头的路径,可以使用regex()方法,例如:regex("/api/.*");// 若不需要匹配任何路径,可以使用none()方法,例如:none().paths(PathSelectors.any()).build() // 结束配置并构建Docket实例.groupName("default"); // 设置分组名称,多个分组名称不能重名
//                .pathMapping("/") // 设置路径映射,用于指定Swagger UI的根路径,默认为/。
//                .protocols(new HashSet<>(Arrays.asList("http", "https"))) // 设置支持的协议
//                .securitySchemes(Collections.singletonList(new ApiKey("token", HttpHeaders.AUTHORIZATION, In.HEADER.toValue()))) // 授权信息设置,必要的header token等认证信息
//                .securityContexts(Collections.singletonList(
//                        SecurityContext.builder()
//                                .securityReferences(Collections.singletonList(new SecurityReference("token", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
//                                .build())); // 设置全局安全上下文,用于指定全局的授权信息return docket;}/*** 该方法的主要作用是通过knife4j生成接口文档,若想要多个分组,则需要配置多个Docket实例* 例如配置第二个Docket实例,分组名称为api** @return Docket 实例,用于Swagger接口文档的配置和生成*/@Beanpublic Docket docket1() {// 构建API信息,用于Swagger文档的元数据ApiInfo apiInfo = new ApiInfoBuilder().title("swagger测试项目接口文档").version("1.0").description("swagger测试项目接口文档").build();// 创建Docket实例并进行配置Docket docket = new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo) // 设置API信息.select() // 进入配置选择器.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)).paths(PathSelectors.ant("/api/**")).build().groupName("api");return docket;}/*** 该方法用于在Spring MVC中配置静态资源的访问路径和位置* 它通过ResourceHandlerRegistry对象来注册资源处理器,* 从而使得特定URL路径下的请求能够映射到应用程序的静态资源上** @param registry ResourceHandlerRegistry实例,用于注册资源处理器*/protected void addResourceHandlers(ResourceHandlerRegistry registry) {// 映射/doc.html到classpath:/META-INF/resources/,以便访问该路径时能够获取到相应的静态文件registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");// 映射/webjars/**到classpath:/META-INF/resources/webjars/,用于支持webjars资源的访问registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}
}

1.3. 启动测试

浏览器访问 http://localhost:8080/doc.html ,访问结果如下图:

界面说明:

左上角的下拉框对应的分组,如下图所示:

 主页对应的是 ApiInfo 里的信息及 Docket 里的 groupName 。

在文档管理-全局参数设置可以设置全局请求头和参数。 

 

2.  使用swagger

2.1. 常用注解

注解

用途

示例

@Api

标记一个控制器类,描述该类的功能

@Api(value = "用户管理相关接口", tags = {"用户管理"})

@ApiOperation

描述一个 API 接口的方法

@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户信息")

@ApiParam

描述方法参数

@ApiParam(name = "id", value = "用户ID", required = true)

@ApiImplicitParam

描述隐式参数,常用于 GET 请求的查询参数

@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header")

@ApiImplicitParams

描述多个隐式参数

@ApiImplicitParams({

@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header"),

@ApiImplicitParam(name = "page", value = "页码", required = false, dataType = "integer", paramType = "query")

})

@ApiResponse

描述方法的响应信息

@ApiResponse(code = 200, message = "成功返回用户信息")

@ApiResponses

描述多个响应信息

@ApiResponses({

@ApiResponse(code = 200, message = "成功返回用户信息"),

@ApiResponse(code = 404, message = "用户不存在")

})

@ApiModel

描述一个模型类

@ApiModel(description = "用户信息")

@ApiModelProperty

描述模型类的属性

@ApiModelProperty("主键值")

@ApiIgnore

忽略某个方法或类,不生成 API 文档

@ApiIgnore

@ApiExample

描述 API 示例请求

@ApiExample(value = "获取用户信息示例", source = "GET /users/{id}")

2.2. 使用示例

controller层使用示例:

import com.zjp.knife4jswaggerdemo.pojo.User;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@Api(value = "用户管理相关接口", tags = {"用户管理"})
public class UserController {@GetMapping("/getUser")@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户信息")@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header"),@ApiImplicitParam(name = "page", value = "页码", required = false, dataType = "integer", paramType = "query")})@ApiResponses({@ApiResponse(code = 200, message = "成功返回用户信息"),@ApiResponse(code = 404, message = "用户不存在")})public User getUser(@ApiParam(name = "id", value = "用户ID", required = true) @RequestParam Integer id) {User user = new User();user.setId(1);user.setName("Alice");user.setAge(18);user.setSex("female");return user;}
}

 实体类使用示例:

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(value = "用户信息", description = "用户信息实体类")
public class User {@ApiModelProperty(value = "主键值", example = "1001")private Integer id;@ApiModelProperty(value = "名称", example = "Bob")private String name;@ApiModelProperty(value = "年龄", example = "32")private Integer age;@ApiModelProperty(value = "性别", example = "male")private String sex;
}

2.3. 启动测试

浏览器访问 http://localhost:8080/doc.html ,访问结果如下图:

实体类信息如下(不调用实体类这里不会展示实体类信息):

 接口文档:

测试接口:

3.  其他配置

属性默认值说明值
knife4j.enablefalse是否开启Knife4j增强模式
knife4j.corsfalse是否开启一个默认的跨域配置,该功能配合自定义Host使用
knife4j.productionfalse是否开启生产环境保护策略,详情参考文档
knife4j.basic对Knife4j提供的资源提供BasicHttp校验,保护文档
knife4j.basic.enablefalse关闭BasicHttp功能
knife4j.basic.usernamebasic用户名
knife4j.basic.passwordbasic密码
knife4j.documents自定义文档集合,该属性是数组
knife4j.documents.group所属分组
knife4j.documents.name类似于接口中的tag,对于自定义文档的分组
knife4j.documents.locationsmarkdown文件路径,可以是一个文件夹(classpath:markdowns/*),也可以是单个文件(classpath:md/sign.md)
knife4j.setting前端Ui的个性化配置属性
knife4j.setting.enable-after-scripttrue调试Tab是否显示AfterScript功能,默认开启
knife4j.setting.languagezh-CNUi默认显示语言,目前主要有两种:中文(zh-CN)、英文(en-US)
knife4j.setting.enable-swagger-modelstrue是否显示界面中SwaggerModel功能
knife4j.setting.swagger-model-nameSwagger Models重命名SwaggerModel名称,默认
knife4j.setting.enable-document-managetrue是否显示界面中"文档管理"功能
knife4j.setting.enable-reload-cache-parameterfalse是否在每个Debug调试栏后显示刷新变量按钮,默认不显示
knife4j.setting.enable-versionfalse是否开启界面中对某接口的版本控制,如果开启,后端变化后Ui界面会存在小蓝点
knife4j.setting.enable-request-cachetrue是否开启请求参数缓存
knife4j.setting.enable-filter-multipart-apisfalse针对RequestMapping的接口请求类型,在不指定参数类型的情况下,如果不过滤,默认会显示7个类型的接口地址参数,如果开启此配置,默认展示一个Post类型的接口地址
knife4j.setting.enable-filter-multipart-api-method-typePOST具体接口的过滤类型
knife4j.setting.enable-hostfalse是否启用Host
knife4j.setting.enable-host-textfalseHOST地址
knife4j.setting.enable-home-customfalse是否开启自定义主页内容
knife4j.setting.home-custom-path主页内容Markdown文件路径
knife4j.setting.enable-searchfalse是否禁用Ui界面中的搜索框
knife4j.setting.enable-footertrue是否显示Footer
knife4j.setting.enable-footer-customfalse是否开启自定义Footer
knife4j.setting.footer-custom-contentfalse自定义Footer内容
knife4j.setting.enable-dynamic-parameterfalse是否开启动态参数调试功能
knife4j.setting.enable-debugtrue启用调试
knife4j.setting.enable-open-apitrue显示OpenAPI规范
knife4j.setting.enable-grouptrue显示服务分组

3.1. 访问权限控制

对应官网原文:3.5 访问权限控制 | Knife4j

3.1.1. 生产环境禁用

目前Springfox-Swagger以及Knife4j提供的资源接口包括如下:

资源说明
/doc.htmlKnife4j提供的文档访问地址
/v2/api-docs-extKnife4j提供的增强接口地址,自2.0.6版本后删除
/swagger-resourcesSpringfox-Swagger提供的分组接口
/v2/api-docsSpringfox-Swagger提供的分组实例详情接口
/swagger-ui.htmlSpringfox-Swagger提供的文档访问地址
/swagger-resources/configuration/uiSpringfox-Swagger提供
/swagger-resources/configuration/securitySpringfox-Swagger提供

 springdoc以及Knife4j提供的资源接口包括如下:

资源说明
/doc.htmlKnife4j提供的文档访问地址
/v3/api-docsspringdoc提供的实例接口
/v3/api-docs/swagger-configspringdoc提供的分组接口
/v3/api-docs/**分组
/swagger-ui/index.htmlspringdoc提供的文档访问地址

当我们部署系统到生产系统,为了接口安全,需要屏蔽所有Swagger的相关资源

如果使用SpringBoot框架,只需在application.properties或者application.yml配置文件中配置:

knife4j:# 开启增强配置 enable: true# 开启生产环境屏蔽production: true

 配置此属性后,所有资源都会屏蔽输出.

效果图如下:

 3.1.2. 登录认证

不管是官方的swagger-ui.html或者doc.html,目前接口访问都是无需权限即可访问接口文档的,很多朋友以前问我能不能提供一个登陆界面的功能,开发者输入用户名和密码来控制界面的访问,只有知道用户名和密码的人才能访问此文档

做登录页控制需要有用户的概念,所以相当长一段时间都没有提供此功能

针对Swagger的资源接口,Knife4j提供了简单的Basic认证功能

效果图如下:

允许开发者在配置文件中配置一个静态的用户名和密码,当对接者访问Swagger页面时,输入此配置的用户名和密码后才能访问Swagger文档页面,如果您使用SpringBoot开发,则只需在相应的application.properties或者application.yml中配置如下:

knife4j:# 开启增强配置 enable: true# 开启Swagger的Basic认证功能,默认是falsebasic:enable: true# Basic认证用户名username: test# Basic认证密码password: 123

如果用户开启了basic认证功能,但是并未配置用户名及密码,Knife4j提供了默认的用户名和密码:

admin/123321

 3.2. 请求参数缓存

在默认情况下,在接口调试的情况下,Knifetj对于接口的请求参数都会缓存起来,该配置可以在前端界面中的个性化设置中看到,如下图:

缓存的情况只会在后端没有给属性example的情况下产生,如果后端在写Swagger的注解的时候,给每个字段赋予了example的值,那么,Knife4j不会使用调试时缓存的值,而是会一直使用后端的example值。

当然,开发者也可以在后端控制文档的接口调试功能,针对请求后的参数是否需要缓存(自2.0.6版本开始)

yml配置如下:

knife4j:enable: truesetting:# 对于调试中的请求参数是否缓存进行开启配置,该参数默认为trueenable-request-cache: true

 也可以手动清理缓存:

 3.3. 动态请求参数

方式一:后台开启

开发者也可以通过开启Knife4j的增强配置,进行默认开启,配置如下:

knife4j:enable: truesetting:# 开启动态请求参数,true-开启,false-关闭enable-dynamic-parameter: true

方式二:界面开启

当在配置中勾选该选项后,我们的接口栏会有变化,如下图:

在原本已存在的参数栏下会出现一栏空的参数栏,开发者可以输入参数名称、参数值对参数进行添加

不管是参数名称的变化还是参数值的变化,变化后会自动追加一行新的调试栏参数,效果图如下:

http://www.lryc.cn/news/492321.html

相关文章:

  • 极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【一】
  • C# 在Word文档模板中,按照占位符插入文字或图片
  • 在使用PCA算法进行数据压缩降维时,如何确定最佳维度是一个关键问题?
  • 深度学习3
  • Qt5.14.2的安装与环境变量及一些依赖库的配置
  • PYNQ 框架 - 时钟系统 + pl_clk 时钟输出不准确问题
  • CDAF / PDAF 原理 | PDAF、CDAF 和 LAAF 对比 | 图像清晰度评价指标
  • 类和对象--中--初始化列表(重要)、隐式类型转化(理解)、最后两个默认成员函数
  • uni-app运行 安卓模拟器 MuMu模拟器
  • java 打印对象所有属性的值 循环
  • k8s认证、授权
  • 基于spring boot的纺织品企业财务管理系统论文
  • @RequestBody和前端的关系以及,如何在前后端之间传递数据?
  • 详解登录MySQL时出现SSL connection error: unknown error number错误
  • 【大数据学习 | Spark-Core】Spark的改变分区的算子
  • Spring Boot Web应用开发:测试
  • 服务器数据恢复—光纤存储FC硬盘数据恢复案例
  • Android Binder技术概览
  • 09 —— Webpack搭建开发环境
  • 深度学习模型:卷积神经网络(CNN)
  • Flask 自定义路由转换器
  • 【淘汰9成NLP面试者的高频面题】LSTM中的tanh和sigmoid分别用在什么地方?为什么?
  • gocv调用opencv添加中文乱码的解决方案
  • org.apache.log4j的日志记录级别和基础使用Demo
  • IC数字后端实现之大厂IC笔试真题(经典时序计算和时序分析题)
  • java centos 离线使用sherpa-onnx文字转语音TTS
  • Android 11 三方应用监听关机广播ACTION_SHUTDOWN
  • OpenHarmony-3.驱动HDF
  • 《白帽子讲Web安全》13-14章
  • CSS - CSS One-Line