前言

项目需要一个对外开放的接口文档,以便其他人对接联调。但若依前后端分离使用的是 swagger v3 版本的接口文档组件,生成的接口文档不仅需要登录状态,而且 Swagger UI 默认的界面确实不太理想:

Swagger UI

虽然官方的修改器 Swagger Editor 可以将 http://localhost:1024/dev-api/v3/api-docs 文档的 JSON 格式转化为 html 客户端输出,但界面效果依旧不太理想。

Swagger Editor 导出的 html 页面

之前的项目中有使用过 knife4j 的接口文档,看着整体还不错,并且,可以导出各种格式的离线文档。

knife4j 接口文档界面

接入 knife4j

通过阅读之前的文档 从 Mybatis-Plus 代码生成器(新)到 Swagger,到 springfox-swagger2,springfox-boot-starter,再到 Knife4j,熟悉了一下 swagger 到 knife4j 的流程。正常来说,直接使用

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

替换掉

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

就可以了,因为 knife4j v3.0.3 依赖里正好对应的是 springfox v3.0.0。但若依依赖中对 swagger-models 做了版本替换,备注里说的是,防止进入swagger页面报类型转换错误。所以,直接添加 knif4j 就可以了,不需要去除原来的 swagger3。

<!-- knife4j(swagger3增强版) -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>${knife4j.version}</version>
</dependency>

<!-- Swagger3依赖 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>${swagger.version}</version>
    <exclusions>
        <exclusion>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
        </exclusion>
    </exclusions>
</dependency>

此时可以通过 ip+port+/doc.html 直接访问文档页面。

常用注解

knife4j 属于 swagger 的增强版,除了 swagger 的注解以外,还增加了一些新的注解功能,比如文档排序 @ApiSupport(order = 2)@ApiOperationSupport(order = 1),此时如果不开启 knife4j 注解是无效的(虽然不会报错,但也不生效)。

# Knife4j配置
knife4j:
  # 是否开启Knife4j(swagger 增强版)
  enable: true
  # 开启屏蔽文档资源
  production: false

knife4j.production 默认为 false ,也就是不屏蔽文档资源,如果线上开启屏蔽之后,则访问 doc.html 会有文字提示:You do not have permission to access this page

swagger 常用的注解就这么几个:

  • @Api(value = "指令", tags = {"指令接口"}, hidden = false)
  • @ApiOperation("启动", hidden = false)
  • @ApiModel(description = "通用请求")
  • @ApiModelProperty(value = "设备编号", required = true)
  • @ApiSupport(order = 1)
  • @ApiIgnore

@Api 用于控制器,因为文档是以控制器作为请求分组的,如果只带一个字符串,默认传递值到 value。但不管是 swagger 还是 knife4j 的分组列表上显示都是 tags 值,所以需要优先设置 tags。tags 为 String 数组类型,在设置 tags 之后,如果其他控制器也添加了该 tags,其他分组列表里也会显示该 tags 下的所有请求。hidden 表示隐藏整个控制器请求,默认为 false,与下面的 @ApiIgnore 注解有相同的作用。

@ApiOperation 用于方法,默认 value 显示为请求名。@ApiOperation 也有 tags 属性,猜测跟控制器的 tags 使用方法基本一致。hidden 表示隐藏整个控制器请求,默认为 false,与下面的 @ApiIgnore 注解有相同的作用。

因为使用 body JSON 格式请求,所以在定义的请求 bean 中会用到 @ApiModel@ApiModelProperty

@ApiModel 用于请求模型,其类型元素 description 显示为 请求参数 中的 参数说明

@ApiModelProperty 用户请求模型属性,默认 value 显示为属性名称,required 显示为 是否必须,但对于属性没有强制验证。

如果需要验证字段,可以在定义模型前面添加 @Validated,如:@RequestBody @Validated CommonReqVO commonReqVO,之后在模型属性上添加 @NotBlank(message = "xxx不能为空") 的校验规则(NotBlank)和返回信息。

排序的注解 @ApiSupport 用于控制器,@ApiOperationSupport 用于方法,默认是正序排序。但这个注解只对启用了 knife4j 的接口文档起作用,因为属于增强部分注解。

忽略的注解 @ApiIgnore 可以用于控制器和方法,添加之后整个控制器或者标注了的方法会隐藏不显示。