smart-doc 文档生成器实战


一、部署

1.基于SprinBoot项目,加入pom.xml加入依赖
<build>
        <plugins>
            <!-- 打包跳过测试 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            
            <plugin>
                <groupId>com.github.shalousun</groupId>
                <artifactId>smart-doc-maven-plugin</artifactId>
                <version>2.6.1</version>
                <configuration>
                    <!--指定生成文档使用的配置文件-->
                    <configFile>./src/main/resources/smart-doc.json</configFile>
                    <excludes>
                        <exclude>com.merak.automation:automation-workflow-service</exclude>
                    </excludes>
                </configuration>
                <executions>
                    <execution>
                        <!--不需要在编译项目时自动生成文档可注释phase-->
                        <phase>compile</phase>
                        <goals>
                            <goal>html</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
           
        </plugins>
    </build>

提示:
如果项目采用是Mvn 多module化设计,可通过下述方式排除其它module的依赖与关联 :

 <excludes>
      <exclude>groupId值:merak-hyper-automation-common值</exclude>
   </excludes>

2.指定生成文档使用的配置文件
./src/main/resources/smart-doc.json文件内容:

{
  "serverUrl": "http://127.0.0.1/automation-workflow/",
  "isStrict": false,
  "allInOne": true,
  "outPath": "src/main/resources/static/doc",
  "projectName": "数字员工API开发文档",
  "packageFilters": "com.merak.hyper.automation.workflow.biz.ThirdpartyInterfaceControl",
  "coverOld": true,
  "style": "xt256",
  "showAuthor": false,
  "allInOneDocFileName": "hyper.html",
  "requestExample": "true",
  "responseExample": "true",
  "revisionLogs": [
    {
      "version": "1.0",
      "revisionTime": "2022-12-12 10:30",
      "status": "add",
      "author": "merak",
      "remarks": "desc"
    }
  ]
}

提示:
“packageFilters”:Controller接口对应的package目录,多个用;隔开,也支持正则式如:com.alibaba:.*

二、代码演示

1.类、方法注解

配置packageFilters参数指定的Controller业务类ThirdpartyInterfaceControl:

......
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 *
 * 数字员工第三方(外部)接入接口
 *
 * @apiNote 数字员工第三方(外部)接入接口
 * @tag 数字员工第三方(外部)接入接口
 */
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/api")
public class ThirdpartyInterfaceControl extends BaseController {
    public static final Logger log = LoggerFactory.getLogger(ThirdpartyInterfaceControl.class);
    @Autowired
    private ExecRecServiceIm execRecServiceIm;
    @Autowired
    private WorkflowServiceIm workflowServiceIm;
    /**
     *
     * 云纳管-创建流程关联任务接口
     * @apiNote 云纳管接口-创建任务
     * @param wfId 流程Id
     * @param appAuthVo 应用系统接入对象
     * @return
     * @response
     * {
     *   "code":200,
     *   "data":{
     *  	"id":"1593831683682377730"  #任务ID
     *   }
     *   "msg":"操作成功"
     * }
     */
    @CrossOrigin
    @PostMapping("/cloudnanotubes/{wfId}")
    public AjaxResult addCloudNanotubes(@PathVariable("wfId") String wfId,
                                        @RequestBody @Valid AppAuthVo appAuthVo) {
        String recPkId = execRecServiceIm.addCloudNanotubes(wfId,appAuthVo);
        if( "".equals(recPkId) ){
            return toAjax(false);
        }
        else{
            Map<String,String> map = new HashMap<>();
            map.put("id",recPkId);
            return AjaxResult.success(map);
        }
    }

    /**
     *
     * 云纳管-同步任务结果接口
     * @apiNote 通过任务ID,反馈任务执行的结果(执行整体结果,支持5种日志)
     * @param syncTaskExecuteRecordsVo
     * @return
     * @response
     * {
     *   "code":200,
     *   "msg":"操作成功"
     * }
     */
    @CrossOrigin
    @PostMapping("/cloudnanotubes/synctaskresult")
    public AjaxResult syncTaskResult(@RequestBody @Valid RecordsVo syncTaskExecuteRecordsVo) {
        return toAjax(execRecServiceIm.syncTaskResult(syncTaskExecuteRecordsVo));
    }

    /**
     * 云执行-发起任务
     * @apiNote 通过流程ID+调用者身份触发一次任务并返回触发结果(触发反馈、任务ID)
     * @param wfId 流程Id
     * @param appAuthVo 应用系统接入对象
     * @return com.merak.hyper.automation.common.core.domain.AjaxResult
     * @response
     * {
     *   "code":200,
     *   "data":{
     *  	"id":"1593831683682377730"  #任务ID
     *   }
     *   "msg":"操作成功"
     * }
     */
    @CrossOrigin
    @PostMapping("/cloudnanotubes/cloudtaskstart/{wfId}")
    public AjaxResult cloudtaskstart(@PathVariable("wfId") String wfId,
                                     @RequestBody @Valid AppAuthVo appAuthVo) {
        String recPkId = workflowServiceIm.cloudTaskStart(wfId,appAuthVo);
        if( "".equals(recPkId) ){
            return toAjax(false);
        }
        else{
            Map<String,String> map = new HashMap<>();
            map.put("id",recPkId);
            return AjaxResult.success(map);
        }
    }

    /**
     *
     * 云执行-查询流程
     * @apiNote 通过流程ID查询流程相关信息(名称、描述、所属部门、单次节省时间、所属部门、所属场景、运行设备数量等)
     * @param wfId 流程Id
     * @return: com.merak.hyper.automation.common.core.domain.AjaxResult
     * @response
     * {
     *   "code":200,
     *   "data":{
     *       "object": "any object"
     *   }
     *   "msg":"操作成功"
     * }
     */
    @CrossOrigin
    @GetMapping("/cloudnanotubes/cloudworkflow")
    public AjaxResult queryCloudWorkflow(@RequestParam("wfId") String wfId) {
        BusWorkflow busWorkflow = workflowServiceIm.queryCloudWorkflow(wfId);
        if( null == busWorkflow ){
            return toAjax(false);
        }
        else{
            return AjaxResult.success(busWorkflow);
        }
    }

    /**
     *
     * 云执行-查询任务(支持批量)
     * @apiNote 1 任务ID+调用者身份查询相关任务信息(任务ID、创建时间、执行时长、执行状态等)
     *          2 调用者身份+时间查询相关任务信息(任务ID、创建时间、执行时长、执行状态等)
     * @param appId 身份认证appId
     * @param appSecret 身份认证appSecret
     * @param id 任务ID
     * @param startTime 任务查询开始时间,格式:yyyy-mm-dd HH:mm:ss
     * @param endTime 任务查询终止时间,格式:yyyy-mm-dd HH:mm:ss
     * @return com.merak.hyper.automation.common.core.page.TableDataInfo
     * @author merak
     */
    @CrossOrigin
    @GetMapping("/cloudnanotubes/cloudtask")
    public TableDataInfo cloudtaskList(@RequestParam(name = "appId") String appId,
                                   @RequestParam(name = "appSecret") String appSecret,
                                   @RequestParam(name = "id",required = false) String id,
                                   @RequestParam(name = "startTime",required = false) Date startTime,
                                   @RequestParam(name = "endTime",required = false) Date endTime) {
        startPage(1, 200);
        List<BusWorkflowExecRecords> list = execRecServiceIm.cloudtaskList(appId,appSecret,id,startTime,endTime);
        return getDataTable(list);
    }
}

参数类AppAuthVo:

package com.merak.hyper.automation.common.core.vo.SyncTaskExecute;

import javax.validation.constraints.NotBlank;

/**
 * @author chenjun
 * @version 1.0
 */
public class AppAuthVo {

    /**
     * 身份认证appId
     */
    @NotBlank(message = "身份认证appId不能为空")
    private String appId;
    /**
     * 身份认证appSecret
     */
    @NotBlank(message = "身份认证appSecret不能为空")
    private String appSecret;
    ....get set....
}

参数类RecordsVo:

package com.merak.hyper.automation.common.core.vo.SyncTaskExecute;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @author chenjun
 * @version 1.0
 * @ClassName: SyncTaskExecuteRecordsVo
 * @description: 云纳管同步任务结果vo:通过任务ID,反馈任务执行的结果(执行整体结果,支持5种日志)
 */
public class RecordsVo {
    /**
     * 任务ID
     */
    @NotBlank(message = "任务ID不能为空")
    private String id;//流程执行记录id-任务ID
    /**
     * 执行开始时间:格式yyyy-mm-dd HH:mm:ss
     */
    private Date startTime;//开始执行时间 2022-22-11 11:00:01
    /**
     * 执行终止时间:格式yyyy-mm-dd HH:mm:ss
     */
    private Date endTime;
    /**
     * 执行状态
     * [0:失败,1:完成 ,2:进行中,3:失败,执行中断, 4:失败,业务异常,5:等待,6:终止]
     *@mock 1
     */
    @NotNull(message = "执行状态不能为空")
    private Integer executeState;
    /**
     * 执行日志类型
     * [1:日志步骤 ,2:日志结果,3:业务截图, 4:业务数据,5:业务附件]
     *@mock 1 #或1,2 或1,...5 或1,2,3,4,5
     */
    @NotBlank(message = "执行日志类型不能为空")
    private String busType;//1,2,3,4,5",

    /**
     * 日志步骤对象,busType = 1时有效
     */
    private StepLog recordsteplog;
    /**
     * 日志结果对象,busType = 2时有效
     */
    private Recordsresultlog recordsresultlog;
    /**
     * 业务截图对象,busType = 3时有效
     */
    private Recordspicturelog recordspicturelog;
    /**
     * 业务数据对象,busType = 4时有效
     */
    private Recordsbusinsslog recordsbusinsslog;
    /**
     * 业务附件对象,busType = 5时有效
     */
    private Recordsattachment recordsattachment;

    ....get set....
}

Recordsresultlog类:

package com.merak.hyper.automation.common.core.vo.SyncTaskExecute;

/**
 * @author chenjun
 * @version 1.0
 */
public class Recordsresultlog {
    /**
     * 日志结果内容
     *@mock 巡检业务正常完成
     */
    private String resultLog;
    /**
     * 执行结果 [success:成功;error:失败;]
     *@mock success
     */
    private String executeResult;
    ...set. get.....
}

2.执行、生成html 或 markdown文档

idea—打开Maven容器—选择项目(需要生成文档目标项目)—Lifecycle(clean->install)—Plugins(smart-doc),如下图:
在这里插入图片描述

执行成功后,打开 **.html 或 *.html.md 首页文件
在这里插入图片描述
效果如图:
在这里插入图片描述

三、参考文档

smart-doc
官方文档:入门与使用
1.smart-doc.json 配置参数

{
  "outPath": "C:\\api", // 接口文档输出地址
  "serverUrl": "http://127.0.0.1:8090"// 请求路径
}




// 详细配置,按需设置
{
  "serverUrl": "http://127.0.0.1", //服务器地址,非必须。导出postman建议设置成http://{{server}}方便直接在postman直接设置环境变量
  "pathPrefix": "", //设置path前缀,非必须。如配置Servlet ContextPath 。@since 2.2.3
  "isStrict": false, //是否开启严格模式
  "allInOne": true,  //是否将文档合并到一个文件中,一般推荐为true
  "outPath": "D://md2", //指定文档的输出路径
  "coverOld": true,  //是否覆盖旧的文件,主要用于mardown文件覆盖
  "createDebugPage": true,//@since 2.0.0 smart-doc支持创建可以测试的html页面,仅在AllInOne模式中起作用。
  "packageFilters": "",//controller包过滤,多个包用英文逗号隔开,2.2.2开始需要采用正则:com.test.controller.*
  "md5EncryptedHtmlName": false,//只有每个controller生成一个html文件是才使用
  "style":"xt256", //基于highlight.js的代码高设置,可选值很多可查看码云wiki,喜欢配色统一简洁的同学可以不设置
  "projectName": "smart-doc",//配置自己的项目名称
  "skipTransientField": true,//目前未实现
  "sortByTitle":false,//接口标题排序,默认为false,@since 1.8.7版本开始
  "showAuthor":true,//是否显示接口作者名称,默认是true,不想显示可关闭
  "requestFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始
  "responseFieldToUnderline":true,//自动将驼峰入参字段在文档中转为下划线格式,//@since 1.8.7版本开始
  "inlineEnum":true,//设置为true会将枚举详情展示到参数表中,默认关闭,//@since 1.8.8版本开始
  "recursionLimit":7,//设置允许递归执行的次数用于避免一些对象解析卡主,默认是7,正常为3次以内,//@since 1.8.8版本开始
  "allInOneDocFileName":"index.html",//自定义设置输出文档名称, @since 1.9.0
  "requestExample":"true",//是否将请求示例展示在文档中,默认true,@since 1.9.0
  "responseExample":"true",//是否将响应示例展示在文档中,默认为true,@since 1.9.0
  "requestParamsTable": true, //是否将请求参数表展示在文档中,默认true,@since 2.2.5
  "responseParamsTable": true //是否将响应参数表展示在文档中, 默认true,@since 2.2.5
  "urlSuffix":".do",//支持SpringMVC旧项目的url后缀,@since 2.1.0
  "displayActualType":false,//配置true会在注释栏自动显示泛型的真实类型短类名,@since 1.9.6
@since 2.0.9
  "openUrl": "http://localhost:7700/api",//torna平台地址,填写自己的私有化部署地址@since 2.0.9
  "debugEnvName":"测试环境", //torna环境名称
  "debugEnvUrl":"http://127.0.0.1",//推送torna配置接口服务地址
  "tornaDebug":false,//启用会推送日志
  "ignoreRequestParams":[ //忽略请求参数对象,把不想生成文档的参数对象屏蔽掉,@since 1.9.2
     "org.springframework.ui.ModelMap"
   ],
  "dataDictionaries": [{ //配置数据字典,没有需求可以不设置
      "title": "http状态码字典", //数据字典的名称
      "enumClassName": "com.power.common.enums.HttpCodeEnum", //数据字典枚举类名称
      "codeField": "code",//数据字典字典码对应的字段名称
      "descField": "message"//数据字典对象的描述信息字典
  }],
  "errorCodeDictionaries": [{ //错误码列表,没有需求可以不设置
    "title": "title",
    "enumClassName": "com.power.common.enums.HttpCodeEnum", //错误码枚举类
    "codeField": "code",//错误码的code码字段名称
    "descField": "message"//错误码的描述信息对应的字段名
  }],
  "revisionLogs": [{ //文档变更记录,非必须
      "version": "1.0", //文档版本号
      "revisionTime": "2020-12-31 10:30", //文档修订时间
      "status": "update", //变更操作状态,一般为:创建、更新等
      "author": "author", //文档变更作者
      "remarks": "desc" //变更描述
    }
  ],
  "customResponseFields": [{ //自定义添加字段和注释,一般用户处理第三方jar包库,非必须
      "name": "code",//覆盖响应码字段
      "desc": "响应代码",//覆盖响应码的字段注释
      "ownerClassName": "org.springframework.data.domain.Pageable", //指定你要添加注释的类名
      "ignore":true, //设置true会被自动忽略掉不会出现在文档中
      "value": "00000"//设置响应码的值
  }],
  "customRequestFields": [{ //自定义请求体的注释,@since 2.1.3,非必须
       "name":"code", //属性名
       "desc":"状态码", //描述
       "ownerClassName":"com.xxx.constant.entity.Result", //属性对应的类全路径
       "value":"200", //默认值或者mock值
       "required":true, //是否必填
       "ignore":false //是否忽略
  }],
  "requestHeaders": [{ //设置请求头,没有需求可以不设置
      "name": "token",//请求头名称
      "type": "string",//请求头类型
      "desc": "desc",//请求头描述信息
      "value":"token请求头的值",//不设置默认null
      "required": false,//是否必须
      "since": "-",//什么版本添加的改请求头
      "pathPatterns": "/app/test/**",//请看https://gitee.com/smart-doc-team/smart-doc/wikis/请求头高级配置?sort_id=4178978
      "excludePathPatterns":"/app/page/**"//请看https://gitee.com/smart-doc-team/smart-doc/wikis/请求头高级配置?sort_id=4178978
  },{
      "name": "appkey",//请求头
      "type": "string",//请求头类型
      "desc": "desc",//请求头描述信息
      "value":"appkey请求头的值",//不设置默认null
      "required": false,//是否必须
      "pathPatterns": "/test/add,/testConstants/1.0",//正则表达式过滤请求头,url匹配上才会添加该请求头,多个正则用分号隔开
      "since": "-"//什么版本添加的改请求头
  }],
  "requestParams": [ //公共请求参数(通过拦截器处理的场景),@since 2.2.3,没有需求请不要设置
    {
      "name": "configPathParam",//请求头名称
      "type": "string",//请求头类型
      "desc": "desc",//请求头描述信息
      "paramIn": "path",
      "value":"testPath",//不设置默认null
      "required": false,//是否必须
      "since": "-",//什么版本添加的改请求头
      "pathPatterns": "*",//正则表达式过滤请求头
      "excludePathPatterns":"/app/page/**" //参考请求头中的用法
    },
    {
      "name": "configQueryParam",//请求头名称
      "type": "string",//请求头类型
      "desc": "desc",//请求头描述信息
      "paramIn": "query",
      "value":"testQuery",//不设置默认null
      "required": false,//是否必须
      "since": "-",//什么版本添加的改请求头
      "pathPatterns": "*",//正则表达式过滤请求头
      "excludePathPatterns":"/app/page/**"
    }
  ],
  "rpcApiDependencies":[{ // 项目开放的dubbo api接口模块依赖,配置后输出到文档方便使用者集成
        "artifactId":"SpringBoot2-Dubbo-Api",
        "groupId":"com.demo",
        "version":"1.0.0"
   }],
  "rpcConsumerConfig": "src/main/resources/consumer-example.conf",//文档中添加dubbo consumer集成配置,用于方便集成方可以快速集成
  "apiObjectReplacements": [{ // 自smart-doc 1.8.5开始你可以使用自定义类覆盖其他类做文档渲染,非必须
      "className": "org.springframework.data.domain.Pageable",
      "replacementClassName": "com.power.doc.model.PageRequestDto" //自定义的PageRequestDto替换Pageable做文档渲染
  }],
  "apiConstants": [{//从1.8.9开始配置自己的常量类,smart-doc在解析到常量时自动替换为具体的值,非必须
        "constantsClassName": "com.power.doc.constants.RequestParamConstant"
  }],
  "responseBodyAdvice":{ //自smart-doc 1.9.8起,非必须项,ResponseBodyAdvice统一返回设置(不要随便配置根据项目的技术来配置),可用ignoreResponseBodyAdvice tag来忽略
          "className":"com.power.common.model.CommonResult" //通用响应体
  },
  "requestBodyAdvice":{ 自smart-doc 2.1.4 起,支持设置RequestBodyAdvice统一请求包装类,非必须
         "className":"com.power.common.model.CommonResult"
  },
  "groups": [ // @since 2.2.5, 对不同的controller进行分组
    {
      "name": "测试分组",
      "apis": "com.power.doc.controller.app.*"
    }
  ]
}

2.smart-doc自定义注释tag
smart-doc的实现初衷是通过使用javadoc文档注释来去除注解式的侵入, 因此smart-doc每增加一个功能首先都是去考虑javadoc原生的tag, 下面对smart-doc使用的一些javadoc的注释tag做介绍。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值