编写api文档是一个费时的操作,过程枯燥。那有没有一种可以自动生成api文档的工具呢,答案是有,比如swagger就是可以自动生成的,像yapi、apidoc、showdoc等等是需要我们编辑的,这样较为复杂且容易遗漏。但是他们的界面很好看,那有没有一种好看的的api文档工具呢,答案也是有,swagger文档增强工具knife4j,界面和功能比swagger更好看,但是是基于swagger开发的。
想要使用knife4j非常简单,只要在Springboot项目中引入knife4j的依赖即可
- <dependency>
- <groupId>com.github.xiaoymin</groupId>
- <artifactId>knife4j-spring-boot-starter</artifactId>
- <version>2.0.9</version>
- </dependency>
注意点:引入了knife4j之后会自动引入一个swagger包,且需要注意springboot版本与swagger版本的匹配,否则启动会出现失败,例如此类的错误Failed to start bean ‘documentationPluginsBootstrapper ‘ ; nested exception… 主要原因是Springboot2.6.x高版本与Swagger2版本冲突问题。

会自动给我们引入swagger,因此我们无需单独引入swagger包,否则会引起版本冲突,在使用knife4j的一些增强功能时会报错
1、首先创建一个springboot环境,并且像上方一样引入依赖坐标。

2、创建swagger配置类,注入到springboot容器
- @Configuration
- @EnableSwagger2WebMvc
- public class SwaggerConfig {
- // 创建Docket存入容器,Docket代表一个接口文档
- @Bean
- public Docket webApiConfig() {
- return new Docket(DocumentationType.SWAGGER_2)
- // 创建接口文档的具体信息
- .apiInfo(webApiInfo())
- // 创建选择器,控制哪些接口被加入文档
- .select()
- // 指定@ApiOperation标注的接口被加入文档
- .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
- .build();
- }
-
- // 创建接口文档的具体信息,会显示在接口文档页面中
- private ApiInfo webApiInfo() {
- return new ApiInfoBuilder()
- // 文档标题
- .title("派派洪后台接口管理")
- // 文档描述
- .description("后台接口文档")
- // 版本
- .version("1.0")
- // 联系人信息
- .contact(new Contact("南山北派", "http://baidu.com", "baidu@qq.com"))
- // 版权
- .license("南山北派")
- // 版权地址
- .licenseUrl("http://www.baidu.com")
- .build();
- }
- }
3、创建一个controller,用swagger相关注解来描述生成api文档
- @RestController
- @RequestMapping("user")
- @Api(tags = "用户管理")
- @ApiSupport(author = "南山北派")
- public class UserController {
-
- HashMap<String, String> userMap = new HashMap<String, String>() {
- {
- put("zhangsan", "张三");
- put("lisi", "李四");
- put("wangmazi", "王麻子");
- put("redmi", "红米");
- put("huawei", "华为");
- }
- };
-
- @GetMapping("getName/{userName}")
- @ApiOperation("查找用户名的真实姓名")
- @ApiOperationSupport(author = "派派洪")
- public String getName(@PathVariable("userName") @ApiParam("用户名") String userName) {
- if (userMap.containsKey(userName)) {
- return userMap.get(userName);
- }
- return "账号不存在";
- }
- }
4、启动项目可以访问ip:端口/doc.html即可看到knife4j的文档界面

使用knife4j增强功能的前提是要在yaml配置中开启增强模式
- knife4j:
- enable: true
swagger只能给整个文档添加作者,不能针对某个接口单独添加作者。knife4j中可以有2种方式给接口添加作者:



目前Springfox-Swagger以及Knife4j提供的资源接口包括如下:
| 资源 | 说明 |
| /doc.html | Knife4j提供的文档访问地址 |
| /v2/api-docs-ext | Knife4j提供的增强接口地址,自 2.0.6版本后删除 |
| /swagger-resources | Springfox-Swagger提供的分组接口 |
| /v2/api-docs | Springfox-Swagger提供的分组实例详情接口 |
| /swagger-ui.html | Springfox-Swagger提供的文档访问地址 |
| /swagger-resources/configuration/ui | Springfox-Swagger提供 |
| /swagger-resources/configuration/security | Springfox-Swagger提供 |
swagger中要实现生产环境关闭文档资源需要在配置类中进行编码,判断环境,比较麻烦。knife4j中只需要在对应环境的配置中添加配置即可
- spring:
- profiles: prod # 指定为生产环境
- knife4j:
- production: true # 开启屏蔽文档资源
注意:如果正常非生产环境下不屏蔽文档,那么引入了springsecurtiy或者自定义拦截器的时候,要排除掉上述表格中的文档资源,否则在非屏蔽状态下也将无法访问到文档资源
接口排序的方式有2种:
通常我们在开发接口时,比如一个新增接口和一个修改接口,修改接口需要传递主键id、而新增接口则不需要传递此属性,但大部分情况,我们只写一个Model类,此时在新增接口时显示主键id会显得很多余。使用自定义增强注解@ApiOperationSupport中的ignoreParameters属性,可以强制忽略要显示的参数
我们给User实体新增一个id属性
- @Data
- @ApiModel("用户实体")
- public class User {
- @ApiModelProperty
- private Integer id;
- @ApiModelProperty("用户名")
- private String userName;
- @ApiModelProperty("姓名")
- private String name;
- }
然后新增一个新增用户的接口方法,用表单方式接收参数,但是忽略掉id。在@ApiOperationSupport中的ignoreParameters属性中填写忽略的属性名称即可
- @PostMapping("/addUser")
- @ApiOperation("添加一个用户")
- @ApiOperationSupport(author = "南山北派", ignoreParameters = "id")
- public String addUser(User user){
- if (userMap.containsKey(user.getUserName())) {
- return "用户已经存在";
- }
- userMap.put(user.getUserName(), user.getName());
- return "添加成功:"+ user.getUserName();
- }

注意:
ignoreParameters支持以数组形式添加多个忽略参数
ignoreParameters支持忽略级联对象的参数,比如User实体类中有个Address类型的属性addr,那么如果想要忽略Address的属性id,那么只需要配置为ignoreParameters = addr.id即可
如果要忽略的参数过多,可以使用includeParameters反向配置
如果是以@RequestBody形式接收参数,那么ignoreParameters中填写参数名.要忽略的属性名即可
- @PostMapping("/addUser2")
- @ApiOperation("添加一个用户")
- @ApiOperationSupport(author = "南山北派", ignoreParameters = "user.id")
- public String addUser2(@RequestBody User user){
- if (userMap.containsKey(user.getUserName())) {
- return "用户已经存在";
- }
- userMap.put(user.getUserName(), user.getName());
- return "添加成功:"+ user.getUserName();
- }

注意:
ignoreParameters支持以数组形式添加多个忽略参数
ignoreParameters支持忽略级联对象的参数,比如User实体类中有个Address类型的属性addr,那么如果想要忽略Address的属性id,那么只需要配置为ignoreParameters = user.addr.id即可
如果要忽略的参数过多,可以使用includeParameters反向配置
AfterScript功能是Knife4j自2.0.6版本开始新增的一项特性功能,在每个接口进行调试Tab中,开发者可以根据Knife4j提供的全局变量,在接口调用之前编写一段JavaScript脚本,当接口调用成功后,Knife4j会执行该脚本
主要应用场景:针对JWT类型的接口,调用登录接口后,每个接口请求时带上Token参数,此时可以通过该脚本动态赋值全局token参数,省去复制粘贴的麻烦
我们新增一个登录接口,返回token参数
- @PostMapping("login")
- @ApiOperation("登录")
- public HashMap<String, Object> login() {
- HashMap<String, Object> result = new HashMap<>(2);
- result.put("success", true);
- result.put("token", "123456");
- return result;
- }
然后在knife4j文档中针对这个登录接口编写AfterScript,取出返回的token,设置到每一个请求的请求头中
- var success=ke.response.data.success;
- if(success===true){
- // 获取token
- var token=ke.response.data.token;
- // 设置当前逻辑分组下的全局Header
- ke.global.setHeader("Authorization", "Bearer " + token);
- }

这样的效果是,请求login接口成功返回token后,后续调试其他所有接口时会自动给请求头中添加token参数,无需手动添加

Knife4j提供基于UI临时设置全局参数功能,例如后台全局token参数等.提供该功能主要是方便开发者进行调试
目前全局参数功能主要提供两种参数类型:query(表单)、header(请求头)
如果后端Swagger有配置全局参数,该功能可以无视
