Api Savior 文档生成 idea 插件进阶教程

2023-11-16

原文地址见 Github Wiki

Spring MVC 注解支持表

注解 注解字段 是否支持 作用描述 备注
@RequestMapping value/path 支持 绑定一个或多个 url
@RequestMapping method 支持 限制请求的 HTTP 方法类型
@RequestMapping consumes 不支持 限制请求 Content-Type必须被此字段包含,否则抛出异常
@RequestMapping produces 不支持 限制请求 Accept 必须与此字段对应,否则抛出异常
@GetMapping 同 @RequestMapping 支持 @RequestMapping + 限制方法类型为 GET
@PostMapping 同 @RequestMapping 支持 @RequestMapping + 限制方法类型为 POST
@PutMapping 同 @RequestMapping 支持 @RequestMapping + 限制方法类型为 PUT
@DeleteMapping 同 @RequestMapping 支持 @RequestMapping + 限制方法类型为 DELETE
@RequestBody 支持 修饰的参数在一系列操作下可与HTTP 请求 Body 映射 插件读取后会将除此之外的参数拼接到 url 上,请求示例则展示为 json 格式
@RequestParam value/name 支持 覆盖参数变量名
@RequestParam required 支持 指定是否必填,默认为 true

注释 / Swagger 注解对应表

本插件支持读取注释 / 注解信息来生成文档,因为 Swagger 用户比较多,考虑到最小成本改造,注解采用的正是 Swagger 这一套,注释则是自己随便定义了一些 tag,具体见下表格!

注解 注解字段 对应注释 作用说明 备注
@Api tags #tags 或 @tags 接口分组名称 插件将此字段信息用于两处(批量生成时的按类分组生成的文档文件名/Postman 文件夹名称)
@Api description 不带注释 tag 部分连起来(可换行)或@description 接口分组描述 分组描述用不上,因此我将其作为 tags 的备用,无 tags 字段时,使用此字段。具体逻辑见代码 (cn.gudqs7.plugins.docer.pojo.annotation.CommentInfo#getItemName)
@Api hidden #hidden 或 @hidden 隐藏此类下所有接口 即跳过此类下所有接口,不生成(但类上直接右键时会忽略此字段,毕竟都指名道姓了,再忽略就不合理了!
@ApiOperation value 不带注释 tag 部分连起来(可换行) 接口名称(接口简述)
@ApiOperation notes #notes 或 @notes 接口详细描述
@ApiOperation hidden #hidden 或 @hidden 隐藏该接口 即跳过此接口,不生成(但方法上直接右键时会忽略此字段,毕竟都指名道姓了,再忽略就不合理了!
@ApiOperation tags 不支持 覆盖 Controller 上 @Api 的 tags 字段,将接口分组 暂不支持,个人无这个需求,目前分组逻辑是类下的为一组,放到同一个文件下,不同包下不同文件夹。(主要目前代码逻辑要支持改动挺大的)
@ApiOperation 其他字段 不支持
@ApiParam name 不支持 覆盖变量名 Swagger 本身无法对 MVC 规则变动,一般需搭配 @RequestParam,而本插件是支持 @RequestParam 的
@ApiParam value @param 后面非 tagKey=tagValue 部分 字段描述
@ApiParam required @param xxx required 字段是否必填 默认为 required=false,可写为 required=true,也可直接写为 required
@ApiParam example @param xxx example=yyy 字段示例值,字段默认值
@ApiParam hidden @param xxx hidden 隐藏改字段 写法同 required,凡是 bool 值均如此
@ApiModel value 类注释中非 tag 部分(可换行) 类的简述
@ApiModel description 不支持 类的描述 暂不支持,后续考虑加上吧,用处不大。
@ApiModelProperty value 字段注释中非 tag 部分(可换行)
@ApiModelProperty notes #notes 或 @notes
@ApiModelProperty example #example 或 @example
@ApiModelProperty required #required 或 @required 值为 true 或 false,由于默认值为 false,因此希望指定为 true 时,可省略值不填,即 @required == @required true(所有bool类型都如此)
@ApiModelProperty hidden #hidden 或 @hidden 同上
@ApiModelProperty name 不支持 覆盖字段变量名 暂不支持,考虑到目前没遇到前后的名称风格不一致的情况(前端无话语权),暂时就这样吧!

更多有用的注释/注解

虽然提到了注解,但更多时候,我都是增加注释来完善文档的,毕竟注解的侵入性较高,还需要增加依赖 jar。

注释

@ 或 #,其实都一样

可能你已经注意到了,上面的表格对应注释总是有两种写法,但他们其实只有前缀不同。
我在代码中解析时,两个符号都会判断,等同对待,因此任一种写法都是 OK 的。
之所以会加一个 # 开头,主要是考虑大部分同学并不知道(我也不知道)如何设置自定义注释 tag,以确保 IDEA 某条规则解析时不会以警告处理。而 #,反而不会触发这条报警规则!

注释还是注解? @important 说了算!

虽然你有注解,但我偏喜欢用注释来生成文档,此时需要使用此注解来告诉插件,使用注释而忽略注解!
之所以这么设计,是因为我虽然更偏爱注释,但也知道大部分注释都是不完整的,而注解则一般较为完整;因此设计优先级时,存在注解则优先使用注解的信息;
于是,我们需要一种方式来提高注释的优先级;此时我便想到了 CSS 的 !important,于是添加了这个注解。
该注释值为 true/false,一般写作 #important 即可。
该注释支持位置如下:类上,字段上,方法上,参数中(即 @param 这行,注意参数的注释以 xx=xx 格式,不同于其他三处写法)

接口并非成功或失败?有多种状态?试试 @code!

若您的接口有多个返回状态码,一般为错误码;
您可使用 @code 50001 错误信息xxxx 来描述这个状态,若有多个,则多写几行即可!

请看一个示例:

/**
 * 新增一个用户
 *
 * @param createUserRequest 用户信息
 * @return 操作是否成功
 * #hiddenResponse totalCount
 * #code 10001 用户昵称已存在
 * #code 10002 用户年龄范围无效, 即用户年龄需在0~200之间的数字
 */
@PostMapping("/createUser")
public BaseResponse<Boolean> createUser(CreateUserRequest createUserRequest) {
    return BaseResponse.success();
}

生成文档如下图,将多出一段 Code 含义信息表格
在这里插入图片描述

友情提示,该功能 Swagger 也支持,请翻到看下面注解篇查看!

某个入参字段或返回值字段不需要出现在这个接口,但会出现在那个接口,怎么办?

有时候,部分数据传输类被多个接口复用,但某个接口可能不需要某个字段(不论入参出参),此时我们可以使用 @hiddenRequest@hiddenResponse 来排除字段;
类似的,你也可以使用 @onlyRequest@onlyResponse 来指定仅需要的字段。
其中 request 后缀指代入参,response 后缀指代出参。
另外,排除和仅包含只能出现一个,否则排除优先级更高,另一个则不会起作用。
关于出参,用法比较确定,毕竟只有一个返回值,以此为根对象,指定字段非常方便;如上个示例中我就隐藏了 totalCount 这个分页相关的出参,其为返回类型下的一个字段;也可以使用 data.xxx 这种格式,通过 . 来指定多层结构下的字段。
而入参,我采用的方式是以 Spring MVC 的解析方式为准,即若所有参数以 application/x-www-form-urlencoded 方式绑定,则表单中的组件名称与变量名称对应;
且当参数为对象类型时,其下的字段与表单中组件名称一致,而不是带有参数的变量名为前缀;如上个示例中,createUserRequest 这个变量就是如此。
总计就是不带有参数变量名为前缀的写法。
这与 knife4j 定义的 @ApiOperationSupport 注解中 includeParameters,ignoreParameters 并不相同;
不过您不用担心,我在程序中已经做了处理,使用其注解时,按照 knife4j 的写法来即可,插件依然能正确识别。

使用 @json 或 @date 来指定日期时间格式

两个注释作用一样,@date 的优先级高;
此注释只能用于字段上。

示例:

/**
 * 开始时间(精度为天)
 * @json yyyy-MM-dd
 * @data yyyy-MM-dd
 */
private Date startTime;

生成的文档的结果如下:

{
  "startTime": "2022-05-29"
}

此注释依据 @JsonFormat@DateTimeFormat 注解字段 pattern 演化而来,因此使用注解也会识别,都存在时,注解优先级高!(@important 此时无效)

使用 @noResponse 来取消 Postman 请求下的示例生成。

如题,添加注释后,生成的 Postman 请求下,返回示例将不生成!
此注释可用于类上,方法上,方法上优先级高(就近原则)。

使用 @guid 和 @random 来控制示例值的生成

您可通过 @guid 来指定示例值为一个 GUID;
使用 @random 来指定字符串示例值的生成时随机的(有字段描述时,非随机,此时可用注释指定为随机,无字段描述时,默认随机);
这两个注释仅适用于字符串类型的字段;
此注释可用于,方法参数上,字段上。

注解

与 @code 对应的 @ApiResponse 和 @ApiResponses
  • @ApiResponsecodemessage 分别对应 Code 和 含义
  • @ApiResponses 则用于包含多个 @ApiResponse
与 @onlyRequest/@hiddenRequest 对应的 @ApiOperationSupport
  • 注意此注解仅 knife4j 拥有。
  • 上面有提到,knife4j 的写法是包含参数变量作为前缀的,和我注释的写法是不一样的,请不要混淆两者!
  • knife4j 仅支持入参,不支持出参,而我的注释是均支持,您可以在注解的基础上,使用注释来设置出参,这样是可以生效的。(这点适用于绝大多数更多注释)
与 @json/@date 对应的 @JsonFormat 和 @DateTimeFormat
  • @JsonFormatpattern 字段值与注释 @json 对应。
  • @DateTimeFormatpattern 字段值与注释 @date 对应。
Hibernate validator 的部分注解支持
  • @NotNull / @NotEmpty / @NotBlank:包含此三个任意一个注解的字段或参数,其是否必填会被设置为 true。
  • @Length:包含此注解时,其字段 max / min 指定了字符长度最大值和最小值,其他参考信息列会多出相应的描述。
  • @Range / @Min / @Max:指定了数字的范围,其他参考信息列会多出相应的描述。

以上的 Hibernate validator 注解均支持在参数上或字段上。

除文档生成外更多功能

导出到 Postman

直接在项目上右键(或某个目录/某个类/任意多选亦可),然后点击 Export Api Interface to Postman 的按钮,如下图

生成的结果文件在文档跟目录(一般为项目路径/api-doc)下 postman 目录下,有个 xxx.postman_collection.json,然后在 Postman 导入界面选择此文件即可。

导出到 Postman 有两种模式

  • 离线模式,生成文件到 postman 目录下。
  • 在线模式,通过配置文件指定 Postman 的 Api Key,可直接通过 api 生成到你的 workspace 下(但无法控制生成到哪个 workspace 下,Postman 提供的 Api 不够完善的问题。)

另外,当仅选择一个类右键时,会根据此类为标识来生成新的 Collection(默认以项目名或在配置文件中指定);
这样做的好处是,不会因为调试某个类把原来的 Collection 覆盖掉。

使用 Search Everywhere 根据 url 搜索并快速跳转到接口定义

双击 Shift 进入 Search Everywhere 后切换到 Api,或使用快捷键 Ctrl + \ Ctrl + Alt + N 进入如下图界面。
此时您可通过 url 或接口描述来搜索并跳转到该接口。

使用智能上下文或后缀快速生成实体类的所有 set 方法 / get 方法

以下展示后缀的使用方法,但使用智能上下文得到的效果是类似的,只是个人认为后缀效率更高一丢丢!

下面演示所使用的基础类


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class Foo {

    private Integer testInt;

    private Long testLong;

    private Float testFloat;

    private Double testDouble;

    private Boolean testBoolean;

}
生成 set
public void usage01() {
    // 用法1, 生成所有 set 方法, 带默认值, 通过 postfix
    Foo foo = new Foo();
    // 取消下面的注释, 光标位于 allset 后面, 按下 Tab 键
//        foo.allset
    // 即可得到下面结果, 且 foo.allset 会自动消失
    foo.setTestInt(0);
    foo.setTestLong(0L);
    foo.setTestFloat(0f);
    foo.setTestDouble(0D);
    foo.setTestBoolean(false);
}
生成 get
public void usage03() {
    // 用法3, 生成所有 get 方法, 通过 postfix
    Foo foo = new Foo();
    // 取消下面的注释, 光标位于 allget 后面, 按下 Tab 键
//        foo.allget
    // 即可得到下面结果, 且 foo.allget 会自动消失
    Integer testInt = foo.getTestInt();
    Long testLong = foo.getTestLong();
    Float testFloat = foo.getTestFloat();
    Double testDouble = foo.getTestDouble();
    Boolean testBoolean = foo.getTestBoolean();
}

Lombok 的 @Builder 快速生成所有赋值方法的调用链

public void usage04() {
    // 用法4, 生成所有 set 方法, 通过 builder, 通过 postfix
    // 取消下面的注释, 光标位于 allbuilder 后面, 按下 Tab 键
//        Foo.builder().allbuilder
    // 即可得到下面结果
    Foo foo = Foo.builder()
            .testInt(0)
            .testLong(0L)
            .testFloat(0f)
            .testDouble(0D)
            .testBoolean(false)
            .build();
}

根据一段含有源对象(a)/目标对象(b)的 b.setXxx(a.getXxx()) 方法代码生成所有 set 方法以快速实现对象转换

public void usage05() {
    // 用法5, 将 src 的数据赋值给 dest, 常用于两个不同类直接进行 convert(需字段名称相同), 通过 postfix
    Foo src = new Foo();
    Foo dest = new Foo();
    // 取消下面的注释, 光标位于 convert 后面, 按下 Tab 键
//        dest.setTestInt(src.getTestInt());.convert
    // 即可得到下面结果
    dest.setTestInt(src.getTestInt());
    dest.setTestLong(src.getTestLong());
    dest.setTestFloat(src.getTestFloat());
    dest.setTestDouble(src.getTestDouble());
    dest.setTestBoolean(src.getTestBoolean());
}

根据一个入参为源对象(a),返回值为目标对象(b)的方法声明,生成对象转换方法

public Foo usage09(Foo src) {
    // 用法9 通过在方法名称上触发 Show Context Actions, 快捷键(如 Alt + Enter 或右键菜单选择)
    //  可看到 Generate Convert,选中后生成下面注释里的内容(不包含 return null;)
//        Foo foo = new Foo();
//        foo.setTestInt(src.getTestInt());
//        foo.setTestLong(src.getTestLong());
//        foo.setTestFloat(src.getTestFloat());
//        foo.setTestDouble(src.getTestDouble());
//        foo.setTestBoolean(src.getTestBoolean());
//        return foo;
    return null;
}

上面这些代码在示例代码块cn.gudqs.example.genset.GenerateSetterAndGetterUsage 下。
欢迎 Clone 体验。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Api Savior 文档生成 idea 插件进阶教程 的相关文章

随机推荐

  • 2.树莓派上程序自启动方式总结(带桌面)

    在树莓派上设置程序上电自动启动的几种方法 1 在pi config中新建autostart文件夹 在下面新建 desktop后缀的文件 具体方式问度娘 忘了 2 在pi文件夹下 修改 bashrc和 profile文件 比如直接运行py文件
  • 图像基本变换---图像二值化(包含OSTU/迭代法/统计法/双峰法/P分位法/最大熵法)

    OSTU法图像二值化 算法说明 Ostu法又叫做最大类间方差法 是一种常用的图像分割算法 基本算法思想是根据初始阈值把图像分为两类 然后计算两类之间的方差 更新阈值 重新计算类间方差 当满足类间方差最大时的阈值 即为所求最佳阈值 具体过程如
  • mybatis中关于example类详解mybatis的Example[Criteria]的使用

    一 什么是example类 mybatis generator会为每个字段产生如上的Criterion 如果表的字段比较多 产生的Example类会十分庞大 理论上通过example类可以构造你想到的任何筛选条件 在mybatis gene
  • 基于Pygame框架的交通导流可视化模拟

    目录标题 项目介绍 项目要求 关键技术 项目核心功能 代码 参考资料 源码下载地址 https download csdn net download david2000999 85627883 项目介绍 本项目根据以下项目要求完成的一个py
  • 软件测试大总结

    目录 一 基本内容 二 软件开发的五大模型 1 瀑布模型 2 螺旋模型 3 增量模型 4 迭代模型 5 敏捷模型 三 敏捷模型中的模型 1 V模型 2 W模型 四 测试用例的设计方法 五 测试分类 1 按测试对象划分 2 按照是否可以查看代
  • 【MySQL索引】提高查询速度和效率

    1 认识索引 假设现在大家要去 MySQL 书中找索引的内容 大家应该不会拿着 MySQL 的书一张一张去找 而是会看MySQL 书的目录 然后通过目录找到索引对应的页码 再去对应的页码中查看索引的内容 索引的优点 索引就相当于书的目录 运
  • 命令行操作MySQL - 调整列的完整性约束

    这是命令行操作MySQL数据库系列博客的第十一篇 今天这篇博客记录如何 调整列的完整性约束 调整 主键 外键 非空 唯一 自增长和默认值约束 一 主键PK 外键FK和 唯一键UK 查询键的别名 show index 或 keys from
  • 关系型数据库连接表的几种方式

    一 SQL 左外连接 右外连接 全连接 内连接 内连接 a表 id name 1 张3 2 李四 3 王武 b表 id job parent id 1 23 1 2 34 2 3 34 4 a id同parent id 存在关系 内连接 i
  • 设置最小值_allegro软件的绝对传输延迟是什么,绝对传输延迟应该怎么设置呢...

    标题 allegro软件的绝对传输延迟是什么 绝对传输延迟应该怎么设置呢 我们在用allegro进行PCB设计完成以后 都需要对一组传输的总线进行时序等长 在做时序等长的时候 分为绝对传输延迟与相对传输延迟 绝对传输延迟 顾名思义 信号传输
  • 洛谷 P1026 [NOIP2001 提高组] 统计单词个数

    题目描述 给出一个长度不超过 200 的由小写英文字母组成的字母串 该字串以每行 20 个字母的方式输入 且保证每行一定为 20 个 要求将此字母串分成 k 份 且每份中包含的单词个数加起来总数最大 每份中包含的单词可以部分重叠 当选用一个
  • 从图片中完整切除圆形物体 opencv+python

    面临一个任务就是要图片中的圆形物体切出来 然后做异常点检测 就是看那些圆形物体是异常点 因为异常点检测的方法还在摸索 现在就先把从图片中把圆形物体完整切出的方法写出来 1 首先图片是这样的 圆形物体非常多 2 接下来就是代码部分 impor
  • Pycharm中的常用快捷方式

    最重要的快捷键 ctrl shift A 万能命令行 shift两次 查看资源文件 新建工程第一步操作 module设置把空包分层去掉 compact empty middle package 设置当前的工程是utf 8 设置的Editor
  • 关于OCA,OCP,OCM认证的的区别

    可能大家知道OCA OCP OCM的关系是一个比一个难考 一个比一个含金量高 但是你知道具体的考试科目 考试方式 就业形势区别吗 不知道的话这篇通俗易懂的文章会让你一目了然 区别一 含金量 OCA 数据库专业人员踏上Oracle数据库认证之
  • MySQL数据库入门超级详细教程

    文章目录 MySQL 1 数据库软件安装 2 为什么要用数据库 3 什么是数据库 4 数据库管理系统 DBMS 5 MySQL 介绍 6 SQL 6 1 SQL 语句概述 6 2 SQL 基本操作 7 表结构操作 7 1 创建数据表 7 2
  • Windows10系统下彻底删除卸载MySQL

    本文介绍 在Windows10系统下 如何彻底删除卸载MySQL 1 停止MySQL服务 开始 所有应用 Windows管理工具 服务 将MySQL服务停止 2 卸载mysql server 控制面板 所有控制面板项 程序和功能 将mysq
  • vscode+Electron环境搭建 helloword

    0 Electron是什么简介 Electron 简单来说就是一个基于Chrome Nodejs的容器 可以用纯前端的方式实现跨平台的桌面应用开发 代码由js css html构成 它支持把整个项目编译成exe 由于它支持Nodejs 所以
  • sqli-labs(22)

    接下里我们进入第二二关 好像和第21关一样 cookie的base64加密注入 闭合变成了双引号而已 0X01 构造语句进行尝试 union select 1 2 3 IiB1bmlvbiBzZWxlY3QgMSwyLDMj 嘿嘿 好像成功
  • 我的世界超富的java种子_《我的世界》最富有的四个种子,第一名有4个村庄,这科学吗?...

    原标题 我的世界 最富有的四个种子 第一名有4个村庄 这科学吗 投胎是一项技术活 这个定律在Minecraft同样适用 好的出生点意味着好的开始 但不是人人都有这种运气 没关系 有种子嘛 Seed 382686119982684279 出生
  • Unity 改变鼠标指针的方法

    在网上查的帖子 先看一下 Texture2D ClickedCursorImg 把鼠标指针改为ClickedCursorImg Cursor SetCursor ClickedCursorImg Vector2 zero CursorMod
  • Api Savior 文档生成 idea 插件进阶教程

    原文地址见 Github Wiki Spring MVC 注解支持表 注解 注解字段 是否支持 作用描述 备注 RequestMapping value path 支持 绑定一个或多个 url RequestMapping method 支