【SpringBoot框架篇】23.集成smart-doc插件零侵入自动生成RESTful格式API文档

1.简介

smart-doc是一款同时支持JAVA REST API和Apache Dubbo RPC接口文档生成的工具,smart-doc在业内率先提出基于JAVA泛型定义推导的理念, 完全基于接口源码来分析生成接口文档,不采用任何注解侵入到业务代码中(swagger则需要写各种注解,严重影响开发效率)。你只需要按照java-doc标准编写注释, smart-doc就能帮你生成一个简易明了的Markdown、HTML5、Postman Collection2.0+、OpenAPI 3.0+的文档。

git官网地址: https://gitee.com/smart-doc-team/smart-doc
环境要求: maven 3.3.9+ , jdk 1.8+

2.配置准备

2.1 添加maven插件

在应用的pom文件中添加插件

    <build>
        <plugins>
            <plugin>
                <groupId>com.github.shalousun</groupId>
                <artifactId>smart-doc-maven-plugin</artifactId>
                <version>2.2.8</version>
                <configuration>
                    <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
                    <configFile>./src/main/resources/smart-doc.json</configFile>
                    <!--指定项目名称-->
                    <projectName>测试</projectName>
                    <!--smart-doc实现自动分析依赖树加载第三方依赖的源码,如果一些框架依赖库加载不到导致报错,这时请使用excludes排除掉-->
                    <excludes>
                        <!--格式为:groupId:artifactId;参考如下-->
                        <exclude>com.alibaba:fastjson</exclude>
                    </excludes>
                    <!--自1.0.8版本开始,插件提供includes支持,配置了includes后插件会按照用户配置加载而不是自动加载,因此使用时需要注意-->
                    <!--smart-doc能自动分析依赖树加载所有依赖源码,原则上会影响文档构建效率,因此你可以使用includes来让插件加载你配置的组件-->
                    <includes>
                        <!--格式为:groupId:artifactId;参考如下-->
                        <include>com.alibaba:fastjson</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <!--如果不需要在执行编译时启动smart-doc,则将phase注释掉-->
                        <phase>compile</phase>
                        <goals>
                            <!--smart-doc提供了html、openapi、markdown等goal,可按需配置-->
                            <goal>html</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2.2 创建配置文件

在应用的resources目录下创建smart-doc.json配置文件

{
  "outPath": "src\\main\\resources\\static",
  "requestHeaders": [
    {
      "name": "token",
      "type": "string",
      "desc": "身份凭证",
      "value":"",
      "required": false,
      "since": "-"
    }],
  "serverUrl": "http://localhost:8023",
  "projectName": "测试项目RESTful文档",
  "packageFilters": "com.ljm.boot.smartdoc.controller"
}
参数描述
outPath配置文档生成目录,本文配的是相对路径,会在应用的resources\static目录下生成
serverUrl文档中接口访问的地址
requestHeaders配置默认的请求头参数(一般前后端分类的项目都是通过在header里添加token参数进行身份认证的)
projectName文档名称
packageFilters指定需要生成Api文档的包,会递归解析 (如果不配置,默认扫描所有包含@Controller,@RestController的类文件)

2.3 添加统一返回数据格式类

public class JsonResult<T>  implements Serializable {
    /**
     * 成功标识 200成功,其它异常
     */
    private int code=200;
    /**
     * 提示信息
     */
    private String msg;
    /**
     * 数据
     */
    private T data;
    /**
     * 响应时间戳
     */
    private String timestamp;
    private static final long serialVersionUID = -7268040542410707954L;
    protected static String successMessage = "操作成功";
    protected static String errorMessage = "操作失败";
    public JsonResult() {}
    public JsonResult(int code) {
        this.setCode(code);
        this.setTimestamp(String.valueOf(System.currentTimeMillis()));
    }
    public JsonResult(int code, String msg) {
        this(code);
        this.setMsg(msg);
    }
    public JsonResult(int code, String msg, T data) {
        this(code, msg);
        this.setData(data);
    }
    public static JsonResult successResult() {
        return new JsonResult(HttpStatus.OK.value(), successMessage);
    }
    public static JsonResult successResult(String msg) {
        return new JsonResult(HttpStatus.OK.value(), defaultSuccessMsg(msg));
    }
    public static <T> JsonResult<T> successResult(T obj) {
        return new JsonResult(HttpStatus.OK.value(), successMessage, obj);
    }
    public static  <T>  JsonResult<T> successResult(String msg, T obj) {
        return new JsonResult(HttpStatus.OK.value(), defaultSuccessMsg(msg), obj);
    }
    public static JsonResult failureResult() {
        return new JsonResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), errorMessage);
    }
    public static JsonResult failureResult(Integer code, String msg) {
        return new JsonResult(code, defautlErrorMsg(msg));
    }
    public static JsonResult failureResult(Integer code, String msg, Object data) {
        return new JsonResult(code, defautlErrorMsg(msg), data);
    }
    public static JsonResult failureResult(String msg) {
        return new JsonResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), defautlErrorMsg(msg));
    }
    public static JsonResult failureResult(Object data) {
        return new JsonResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), errorMessage, data);
    }
    protected static String defautlErrorMsg(String msg) {
        if (StringUtils.hasText(msg)) {
            return msg;
        } else {
            return errorMessage;
        }
    }
    protected static String defaultSuccessMsg(String msg) {
        if (StringUtils.hasText(msg)) {
            return msg;
        } else {
            return successMessage;
        }
    }
}

3.接口实战

3.1 demo接口类

此类写了一套基于RSETful风格的CRUD操作

/**
 * 用户类
 * @author Dominick Li
 * @CreateTime 2021/10/9 11:46
 **/
@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * 获取所有用户信息
     */
    @GetMapping("/")
    public JsonResult<List<User>> findAll() {
        User user = new User();
        user.setUsername("test");
        user.setPassword("123456");
        return JsonResult.successResult(Arrays.asList(user));
    }

    /**
     * 根据用户id获取用户信息
     * @param id 用户Id
     */
    @GetMapping("/{id}")
    public JsonResult<User> findById(@PathVariable String id) {
        User user = new User();
        user.setUsername("test");
        user.setPassword("123456");
        return JsonResult.successResult(user);
    }

    /**
     * 登录 入参方式: @RequestParam
     * @param username 用户名
     * @param password 密码
     */
    @PostMapping("/login")
    public JsonResult login(@RequestParam("username") String username, @RequestParam("password") String password) {
        return JsonResult.successResult();
    }

    /**
     * 添加用户 入参方式: @RequestBody
     */
    @PostMapping("/")
    public JsonResult save(@RequestBody User user) {
        return JsonResult.successResult();
    }

    /**
     * 删除用户
     * @param id 用户Id
     */
    @DeleteMapping("/{id}")
    public JsonResult deleteById(@PathVariable String id) {
        return JsonResult.successResult();
    }
}

3.2 用户模型类

public class User implements Serializable {

    /**
     *  用户id
     *  @ignore
     */
    @JsonIgnore
    private Integer id;
    /**
     * 用户名称
     * @required
     */
    private String username;

    /**
     * 密码
     * @required
     */
    private String password;

    /**
     * 年龄
     */
    private Integer age;
	//省略 get,set 方法...
}

3.3 相关注释描述

接口名称
必须是注释信息里的第一行文字

/**
 * 用户类
 **/
@RestController
@RequestMapping("/user")
public class UserController {
    

接口参数
@PathVariable和@RequestParam
在接口注释名称下面通过 @param 进行参数和描述映射

    /**
     * 根据用户id获取用户信息
     * @param id 用户Id
     */
    @GetMapping("/{id}")
    public JsonResult<User> findById(@PathVariable String id) {}
    /**
     * 登录 入参方式: @RequestParam
     * @param username 用户名
     * @param password 密码
     */
    @PostMapping("/login")
    public JsonResult login(@RequestParam("username") String username, @RequestParam("password") String password) {}

@RequestBody
使用@RequestBody时候,则需要到对应的模型类中添加注释描述即可

    /**
     * 添加用户 入参方式: @RequestBody
     */
    @PostMapping("/")
    public JsonResult save(@RequestBody User user) {
        return JsonResult.successResult();
    }
    
private class User{
    /**
     *  用户id
     *  @ignore
     */
    @JsonIgnore
    private Integer id;

    /**
     * 用户名称
     * @required
     */
    private String username;
}    
参数描述
@ignore接口请求时这个参数忽略掉(文档中不会生成)
@required接口请求时这个参数是必传的(文档中描述会显示required=true)
@JsonIgnore接口返回的JSON数据中忽略该参数(文档中不会生成)
其它的注释@tag描述请查看官网: 自定义tag使用

4.文档生成并查看

4.1 生成文档命令

只写了常用的三种,本文使用的是第一种.其它的请参考官网。
第三种是当项目是父子工程的时候用到的,依赖的maven插件也要在父工程的pom.xml中定义,无需在子工程里配置.

//生成html
mvn -Dfile.encoding=UTF-8 smart-doc:html
//生成markdown
mvn -Dfile.encoding=UTF-8 smart-doc:markdown
//如果是父子工程的情况下,在父工程目录执行mvn命令并通过pl指定模块名称 smartModelName 
mvn smart-doc:markdown -Dfile.encoding=UTF-8  -pl :smartModelName -am

在应用根目录下命令行中执行mvn -Dfile.encoding=UTF-8 smart-doc:html命令,看到BUILD SUCCESS代表着运行成功,然后去resource/static目录下查看文档.
在这里插入图片描述

在这里插入图片描述

4.2 查看

双击api.html文件查看,或者访问项目地址 http://localhost:8023/api.html查看.

在这里插入图片描述

5.集成torna统一管理和测试API文档

如果不需要使用第三方应用管理API文档或测试的可以跳过此章
项目部署使用地址: https://gitee.com/durcframework/torna#%E4%BD%BF%E7%94%A8%E6%AD%A5%E9%AA%A4

部署完成后访问 http://localhost:7700/ 查看项目
账号: admin@torna.cn 密码: 123456

5.1 创建空间并找到3要素(appKey,secret,appToken)

应用启动后登录然后创建空间
在这里插入图片描述
点击刚创建的空间名称跳转到空间里,点击创建项目
在这里插入图片描述
点击开放用户创建一个账号信息
在这里插入图片描述

创建完会自动生成AppKeySecret参数
在这里插入图片描述

点击项目里面的接口文档菜单,然后点击模块列表的添加按钮添加一个模块。
在这里插入图片描述
点击模块里的OpenAPI按钮,然后获取到Token信息
在这里插入图片描述

到此,三要素已经都有了。

5.2 在smart-doc.json中添加三要素

{
  "appKey": "20211009896416441941622784",
  "secret": "JUwrw.7B%69%xa.nBq$,Vd#CZY&T8sh0",
  "appToken": "c7d746791f2947a8b637b0440c65cf62",
  "openUrl": "http://127.0.0.1:7700/api",
  "debugEnvName":"测试环境",
  "debugEnvUrl":"http://127.0.0.1:8023"
}
参数描述
前三个torna应用中创建项目空间和模块的时候会自动生成
openUrl添加torna应用部署的服务器IP(推送文档需要使用)
debugEnvUrl测试接口用的请求地址

5.3 推送文档到torna项目中进行管理

在应用根目录下命令行中执行mvn -Dfile.encoding=UTF-8 smart-doc:torna-rest命令,看到BUILD SUCCESS代表着运行成功,然后在torna中项目文档中刷新即可查看

mvn -Dfile.encoding=UTF-8 smart-doc:torna-rest

5.4 查看项目文档

5.4.1 查看概况视图

在这里插入图片描述

5.4.2 查看详细信息

点击上图中的预览查看详细信息
在这里插入图片描述

5.4.3 在线测试接口

点击4.4.2图片中的调试接口按钮跳转到测试页面进行接口测试
在这里插入图片描述

6.项目配套代码

gitee代码地址

创作不易,要是觉得我写的对你有点帮助的话,麻烦在gitee上帮我点下 Star

【SpringBoot框架篇】其它文章如下,后续会继续更新。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皓亮君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值