smart doc:自动生成接口文档拓展

2023-11-02

smart doc 作为一个接口文档生成工具,可以根据代码的java doc注释,生成接口文档。同时已经对接到Torna接口平台。

鉴于大家用的接口平台五花八门,Torna的功能可能不符合大家的需求,研究下是否可以基于smart doc,拓展功能对接其他接口平台

源码功能分析

定位Torna功能源码

根据插件命令的名称,从 smart-doc-maven-plugin 项目找到 torna-rest 的maven插件命令定义Mojo类 TornaRestMojo

以下即为命令执行入口代码

@Execute(phase = LifecyclePhase.COMPILE)
@Mojo(name = MojoConstants.TORNA_REST_MOJO, requiresDependencyResolution = ResolutionScope.COMPILE)
public class TornaRestMojo extends BaseDocsGeneratorMojo {

    @Override
    public void executeMojo(ApiConfig apiConfig, JavaProjectBuilder javaProjectBuilder) {
        try {
            TornaBuilder.buildApiDoc(apiConfig, javaProjectBuilder);
        } catch (Exception e) {
            getLog().error(e);
        }
    }
}

这里可以看到实现入口为 TornaBuilder.buildApiDoc, 继续跟踪到 smart-doc 项目下的 TornaBuilder

流程主要分为两步:通过buildApiDoc 生成接口文档,再转换数据结构,根据接口配置,推送到Torna

    /**
     * Only for smart-doc maven plugin and gradle plugin.
     *
     * @param config             ApiConfig
     * @param javaProjectBuilder ProjectDocConfigBuilder
     */
    public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
        config.setParamsDataToTree(true);
        DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
        builderTemplate.checkAndInit(config, true);
        ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
        IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
        List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
        apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
        // 将数据转换为Torna的接口格式 并推送到Torna去
        buildTorna(apiDocList, config, javaProjectBuilder);
    }

文档生成部分目前符合我们的需求,看看推送部分,也只是简单的层级数据转换和接口请求。

    /**
     * build torna Data
     *
     * @param apiDocs   apiData
     * @param apiConfig ApiConfig
     * @param builder   JavaProjectBuilder
     */
    public static void buildTorna(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
        TornaApi tornaApi = new TornaApi();
        tornaApi.setAuthor(StringUtil.isEmpty(apiConfig.getAuthor()) ? System.getProperty("user.name") : apiConfig.getAuthor());
        tornaApi.setIsReplace((apiConfig.getReplace() == null || apiConfig.getReplace()) ? 1 : 0);
        Apis api;
        List<Apis> groupApiList = new ArrayList<>();
        //Convert ApiDoc to Apis
        for (ApiDoc groupApi : apiDocs) {
            List<Apis> apisList = new ArrayList<>();
            List<ApiDoc> childrenApiDocs = groupApi.getChildrenApiDocs();
            for (ApiDoc a : childrenApiDocs) {
                api = new Apis();
                api.setName(StringUtils.isBlank(a.getDesc()) ? a.getName() : a.getDesc());
                api.setItems(buildApis(a.getList(), TornaUtil.setDebugEnv(apiConfig, tornaApi)));
                api.setIsFolder(TornaConstants.YES);
                api.setAuthor(a.getAuthor());
                api.setOrderIndex(a.getOrder());
                apisList.add(api);
            }
            api = new Apis();
            api.setName(StringUtils.isBlank(groupApi.getDesc()) ? groupApi.getName() : groupApi.getDesc());
            api.setAuthor(tornaApi.getAuthor());
            api.setOrderIndex(groupApi.getOrder());
            api.setIsFolder(TornaConstants.YES);
            api.setItems(apisList);
            groupApiList.add(api);

        }
        tornaApi.setCommonErrorCodes(buildErrorCode(apiConfig, builder));
        // delete default group when only default group
        tornaApi.setApis(groupApiList.size() == 1 ? groupApiList.get(0).getItems() : groupApiList);
        //Build push document information
        Map<String, String> requestJson = TornaConstants.buildParams(PUSH, new Gson().toJson(tornaApi), apiConfig);
        //Push dictionary information
        Map<String, Object> dicMap = new HashMap<>(2);
        List<TornaDic> docDicts = TornaUtil.buildTornaDic(DocUtil.buildDictionary(apiConfig, builder));
        if (CollectionUtil.isNotEmpty(docDicts)) {
            dicMap.put("enums", docDicts);
            Map<String, String> dicRequestJson = TornaConstants.buildParams(ENUM_PUSH, new Gson().toJson(dicMap), apiConfig);
            String dicResponseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(dicRequestJson));
            TornaUtil.printDebugInfo(apiConfig, dicResponseMsg, dicRequestJson, ENUM_PUSH);
        }
        //Get the response result
        String responseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), new Gson().toJson(requestJson));

        //Print the log of pushing documents to Torna
        TornaUtil.printDebugInfo(apiConfig, responseMsg, requestJson, PUSH);

    }

最后结论

我们的可以完全复用接口文档生成的部分代码,然后将 List<ApiDoc> apiDocList 转换成我们需要的数据结构,融入到其他接口平台中去。不过这过程需要其他接口平台也提供这种接口推送,或者json及其他形式的数据导入。

只需要模仿TornaBuilder 进行拓展实现

以下为实现示例:

/**
 * 自定义文档生成接口推送
 *
 * @author azhuzhu 2022/9/20 15:13
 */
@Slf4j
public class CustomizeBuilder {

    /**
     * build controller api
     *
     * @param config config
     */
    public static void buildApiDoc(ApiConfig config) {
        JavaProjectBuilder javaProjectBuilder = JavaProjectBuilderHelper.create();
        buildApiDoc(config, javaProjectBuilder);
    }


    /**
     * Only for smart-doc maven plugin and gradle plugin.
     *
     * @param config             ApiConfig
     * @param javaProjectBuilder ProjectDocConfigBuilder
     */
    public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
        // 文档结构化数据生成部分完全复用
        config.setParamsDataToTree(true);
        DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
        builderTemplate.checkAndInit(config, true);
        ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
        IDocBuildTemplate docBuildTemplate = BuildTemplateFactory.getDocBuildTemplate(config.getFramework());
        List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
        apiDocList = docBuildTemplate.handleApiGroup(apiDocList, config);
        // 将List<ApiDoc>转换为对应的接口平台的对接接口数据格式,并推送过去 配置的读取方式可以自行拓展
        customizeBuild(apiDocList, config, javaProjectBuilder);
    }

    private static void customizeBuild(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
        String bodyJson = buildBodyJson(apiDocs, apiConfig, builder);
        String responseMsg = OkHttp3Util.syncPostJson(apiConfig.getOpenUrl(), bodyJson);
        log.debug(responseMsg);
    }

    private static String buildBodyJson(List<ApiDoc> apiDocs, ApiConfig apiConfig, JavaProjectBuilder builder) {
        // TODO: 实现数据结构的转换 返回Json
        return "";
    }

}

新建一个项目,引入smart-doc-maven-plugin 作为依赖,如上面代码所示实现自定义的builder,有需要的话创建自定义的插件。

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

smart doc:自动生成接口文档拓展 的相关文章

  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • 序列的排列?

    我有具体数量的数字 现在我想以某种方式显示这个序列的所有可能的排列 例如 如果数字数量为3 我想显示 0 0 0 0 0 1 0 0 2 0 1 0 0 1 1 0 1 2 0 2 0 0 2 1 0 2 2 1 0 0 1 0 1 1 0
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • Junit:如何测试从属性文件读取属性的方法

    嗨 我有课ReadProperty其中有一个方法ReadPropertyFile返回类型的Myclass从属性文件读取参数值并返回Myclass目的 我需要帮助来测试ReadPropertyFile方法与JUnit 如果可能的话使用模拟文件
  • 如何通过 javaconfig 使用 SchedulerFactoryBean.schedulerContextAsMap

    我使用 Spring 4 0 并将项目从 xml 移至 java config 除了访问 Service scheduleService 带注释的类来自QuartzJobBean executeInternal 我必须让它工作的 xml 位
  • 在内存中使用 byte[] 创建 zip 文件。 Zip 文件总是损坏

    我创建的 zip 文件有问题 我正在使用 Java 7 我尝试从字节数组创建一个 zip 文件 其中包含两个或多个 Excel 文件 应用程序始终完成 没有任何异常 所以 我以为一切都好 当我尝试打开 zip 文件后 Windows 7 出
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • Pig Udf 显示结果

    我是 Pig 的新手 我用 Java 编写了一个 udf 并且包含了一个 System out println 其中的声明 我必须知道在 Pig 中运行时该语句在哪里打印 假设你的UDF 扩展了 EvalFunc 您可以使用从返回的 Log
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • Eclipse Maven Spring 项目 - 错误

    I need help with an error which make me crazy I started to study Java EE and I am going through tutorial on youtube Ever
  • Hibernate 的 PersistentSet 不使用 hashCode/equals 的自定义实现

    所以我有一本实体书 public class Book private String id private String name private String description private Image coverImage pr
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 专门针对 JSP 的测试驱动开发

    在理解 TDD 到底是什么之前 我就已经开始编写测试驱动的代码了 在没有实现的情况下调用函数和类可以帮助我以更快 更有效的方式理解和构建我的应用程序 所以我非常习惯编写代码 gt 编译它 gt 看到它失败 gt 通过构建其实现来修复它的过程
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • Java中super关键字的范围和使用

    为什么无法使用 super 关键字访问父类变量 使用以下代码 输出为 feline cougar c c class Feline public String type f public Feline System out print fe

随机推荐

  • 【疑难杂症】vmware虚拟机提示“该虚拟机似乎正在使用中”,并且无法获取所有权解决办法(三步解决虚拟机vmware提示正在使用中的问题)

    目 录 一 背景介绍 二 解决步骤 三 原因说明 四 参考文献 一 背景介绍 最近公司机房意外出现断电 机房的服务器来不及手动关机也都 啪唧 一下突然下了电 于是乎服务器上的vmware虚拟机因为异常中断 出现了如下异常 虚拟机上出现红色叉
  • windows和Linux下用qt开发串口调试助手

    windows下开发串口调试助手 当在Windows环境下使用Qt开发串口调试助手时 可以使用Qt的串口模块 QSerialPort 来实现串口通信功能 下面是一个简单的代码示例 详细说明了如何使用Qt开发串口调试助手 首先 需要在Qt项目
  • rtmp/rtsp/hls公网真正可用的测试地址

    相信大家在调试播放器的时候 都有这样的困惑 很难找到合适的公有测试源 以下是大牛直播SDK GitHub地址 整理的真正可用的直播地址源 其中 rtmp和rtsp的url 用我们播放器验证通过 1 rtmp 58 200 131 2 193
  • Forster论文预积分难理解部分推导(不定期更新)

    预积分 横线上面是今早泡泡机器人推送的推导过程 完全摘抄了下来 但这个式4 1到下一步却很晦涩 下面是详细推导
  • Python获取 只因 弹幕数据+制作词云分析.........就差唱、跳、rap不会了

    人生苦短 我用python 最近在小破站热门上看见了这个 不得不说还是挺不一样的 对吧 什么你说不是 哎呦 你干嘛 咳咳 话不多说 让我们一起来康康 基本开发环境 Python 3 6 Pycharm 相关模块的使用 requests re
  • HTML浮动窗口效果

    因项目中弹出窗口用的是thickbox 但是这个插件不支持多次层级弹出 但是需求需要实现的功能又是在弹出窗口中再次用一个弹出窗口展示效果 就想到了用浮动窗口效果 直接上代码 点击按钮弹出浮动窗口
  • 代码随想录算法训练营day1~18总结

    时间 空间复杂度 解题过程中运用的函数补充说明 数组 day1 http t csdn cn dBSgY day2 http t csdn cn JTDvH 数组总结 链表 day3 http t csdn cn mJx9V day4 ht
  • PAT乙级刷题之路1055 集体照 (25分)

    1055 集体照 25分 拍集体照时队形很重要 这里对给定的 N 个人 K 排的队形设计排队规则如下 每排人数为 N K 向下取整 多出来的人全部站在最后一排 后排所有人的个子都不比前排任何人矮 每排中最高者站中间 中间位置为 m 2 1
  • 动态修改 MeshCollider

    借鉴 https www cnblogs com imteach p 10348744 html using System Collections Generic using UnityEngine RequireComponent typ
  • 关于超参数调优及迁移学习的一些见解

    前言 最近看了一本书 TensorFlow 实战google深度学习框架 其中里面的在第6章中的6 5 2这个小结中 里面有这样的一个代码 具体我就不贴了 总之就是先通过图片数据输入成一个 npy文件 然后通过这个npy文件来输入到模型中
  • 4.20/21实习总结:k8s

    文章目录 什么是k8s 是个软件系统 容器集群管理工具 提供了应用部署 规划 更新 维护的一种机制 1 k8s组件 2 k8s对象 都可以在yaml文件中作为一种API类型来配置 3 namespace名称空间 通过名称空间在同一个物理集群
  • Android开发技巧(三)—— 创建定时任务

    每种手机都有自己的休眠策略 Android手机在长时间不操作时会自动让CPU进入睡眠状态 这就导致JAVA原生Timer的定时任务无法运行 所以我们需要借助Alarm唤醒CPU 一 Alarm机制 Alarm借助了AlermManager类
  • React 常用生命周期函数

    文章目录 React 生命周期图示 创建 constructor render componentDidMount 更新 render componentDidUpdate prevProps prevState 卸载 componentW
  • P2597 [ZJOI2012]灾难【支配树】

    题目链接 这是一道支配树的模板题了 然后写一下我初见支配树的理解 第一次碰到支配树是在昨天的多校第三场的1002 当时我推了个拓扑排序加上LCA的求差 dp a dp b dp lca a b 来解这个问题 然后为了处理出来每个的dp值 我
  • caret教程10:随机森林示例

    我们今天给大家演示下caret包做随机森林分类的一个小例子 同时也给大家看看做预处理和不做预处理两种情况下的模型表现 加载R包和数据 rm list ls library caret Loading required package ggp
  • Jmeter分布式测试的各种坑

    第一坑 启动压力机的时候 直接 jmeter server 会报如下错误 错误原因 127 0 0 1是本机 一个回路地址 没有指定地址 正确的启动方式 启动命令加一个参数 IP地址写压力机对应的地址 jmeter server D jav
  • python爬虫之逆向破解_Python爬虫:一个反爬 JS 逆向分析的例子

    挺久没发爬虫相关的教程啦 今天给大伙分享一下关于网站反爬对请求参数值的加密分析例子 主要还是看看思路 定位加密点 在某网站中进行登录请求 简单抓下包 点击登录按钮之后 可以在浏览器的控制台中看到相关的请求 接着往下拉 可以看到 POST 请
  • 实时CPU设计

    Patmos with Chisel https github com t crest patmos
  • Wireshark使用详解

    文章目录 wireshark简介 抓包原理 抓包 抓包窗口介绍 封包详细信息 Packet Details Pane 过滤信息介绍 显示过滤 抓包过滤 高级功能 数据流追踪 wireshark简介 wireshark是捕获机器上的某一块网卡
  • smart doc:自动生成接口文档拓展

    smart doc 作为一个接口文档生成工具 可以根据代码的java doc注释 生成接口文档 同时已经对接到Torna接口平台 鉴于大家用的接口平台五花八门 Torna的功能可能不符合大家的需求 研究下是否可以基于smart doc 拓展