最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用javadoc注釋自動生成Swagger注解

 更新時間:2023年08月13日 09:20:50   作者:三火哥  
由于現(xiàn)在controller方法上面沒有swagger注解,只能拿到接口url地址,無法獲得接口功能描述,所以本文為大家介紹一下如何利用javadoc注釋自動生成Swagger注解,感興趣的可以了解下

目的

可視化接口管理平臺,通過接口管理平臺一目了然知道接口的作用,接口上面擴展了哪些功能,從而做到對應用程序代碼零侵入

現(xiàn)狀

由于現(xiàn)在controller方法上面沒有swagger注解,只能拿到接口url地址,無法獲得接口功能描述。

值得慶幸的是我們的代碼非常規(guī)范每個方法都有標準的javadoc注釋,于是就想到了獲取javadoc注釋的描述自動生成swagger注解

思路

1,AOP切面,你會發(fā)現(xiàn)根本無法獲取javadoc,這個方案就直接pass掉了

2,讀文件流獲取文件內(nèi)容解析出想要的數(shù)據(jù),雖然可以但是費時費力,不是最優(yōu)的方案

3,使用開源的javaparser難道不香嗎,非常香就它了

javaparser

<dependency>
	<groupId>com.github.javaparser</groupId>
	<artifactId>javaparser-core</artifactId>
	<version>3.25.4</version>
</dependency>
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import com.fuchuang.scm.common.util.ScmAssert;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
 * 通過javadoc注釋自動生成Swagger注解
 *
 * @author xiongyan
 * @date 2023/7/7
 */
public class Sw {
    public static void main(String[] args) throws Exception {
        String clientPath = "/Users/xiongyan/Documents/work/fc-cdc/fc-cdc-api/src/main/java/com/fc/cdc/controller";
        String controllerPath = "/Users/xiongyan/Documents/work/fc-cdc/fc-cdc-api/src/main/java/com/fc/cdc/controller";
        Map<String, ClassOrInterfaceDeclaration> clientMap = Sw.clientMap(clientPath);
        File project = new File(controllerPath);
        ScmAssert.isTrue(project.exists(), "項目路徑不存在");
        for (File file : project.listFiles()) {
            CompilationUnit cu = StaticJavaParser.parse(file);
            ClassOrInterfaceDeclaration classDeclaration = cu.findFirst(ClassOrInterfaceDeclaration.class).orElse(null);
            if (null == classDeclaration) {
                continue;
            }
            String classComment = null;
            Map<String, String> methodCommentMap = new HashMap<>();
            if (classDeclaration.getImplementedTypes().size() > 0) {
                String interfaceName = classDeclaration.getImplementedTypes(0).getNameAsString();
                ClassOrInterfaceDeclaration interfaceDeclaration = clientMap.get(interfaceName);
                if (null == interfaceDeclaration) {
                    continue;
                }
                if (interfaceDeclaration.getJavadoc().isPresent()) {
                    classComment = interfaceDeclaration.getJavadoc().get().getDescription().toText();
                }
                for (MethodDeclaration method : interfaceDeclaration.getMethods()) {
                    if (!method.getJavadoc().isPresent()) {
                        continue;
                    }
                    methodCommentMap.put(method.getNameAsString(), method.getJavadoc().get().getDescription().toText());
                }
            }
            if (StrUtil.isEmpty(classComment)) {
                if (classDeclaration.getJavadoc().isPresent()) {
                    classComment = classDeclaration.getJavadoc().get().getDescription().toText();
                } else {
                    classComment = classDeclaration.getNameAsString();
                }
            }
            if (!classDeclaration.getAnnotationByClass(Api.class).isPresent()) {
                classDeclaration.addAndGetAnnotation(Api.class).addPair("value", "\"" + classComment + "\"");
            }
            for (MethodDeclaration method : classDeclaration.getMethods()) {
                if (method.getAnnotationByClass(ApiOperation.class).isPresent()) {
                    continue;
                }
                String methodComment = methodCommentMap.get(method.getNameAsString());
                if (StrUtil.isEmpty(methodComment)) {
                    if (method.getJavadoc().isPresent()) {
                        methodComment = method.getJavadoc().get().getDescription().toText();
                    } else {
                        methodComment = method.getNameAsString();
                    }
                }
                method.addAndGetAnnotation(ApiOperation.class).addPair("value", "\"" + classComment + "-" + methodComment + "\"");
            }
            FileOutputStream outputStream = new FileOutputStream(file);
            outputStream.write(cu.toString().getBytes());
        }
    }
    private static Map<String, ClassOrInterfaceDeclaration> clientMap(String path) throws FileNotFoundException {
        File project = new File(path);
        ScmAssert.isTrue(project.exists(), "項目路徑不存在");
        Map<String, ClassOrInterfaceDeclaration> clientMap = new HashMap<>();
        for (File file : project.listFiles()) {
            CompilationUnit cu = StaticJavaParser.parse(file);
            if (null == cu) {
                continue;
            }
            ClassOrInterfaceDeclaration classDeclaration = cu.findFirst(ClassOrInterfaceDeclaration.class).orElse(null);
            if (null != classDeclaration && classDeclaration.isInterface()) {
                clientMap.put(classDeclaration.getNameAsString(), classDeclaration);
            }
        }
        return clientMap;
    }
}

效果

/**
 * 數(shù)據(jù)庫管理
 *
 * @author xiongyan
 * @date 2023/03/13
 */
@RestController
@RequestMapping("/web/database")
public class WebDatabaseController {
    /**
     * 分頁列表
     *
     * @param request
     * @return
     */
    @PostMapping("/page")
    public ScmResponse<ScmPage<DatabaseDto>> page(@RequestBody DatabaseRequest request) {
        return ScmResponseUtil.success();
    }
}
/**
 * 數(shù)據(jù)庫管理
 *
 * @author xiongyan
 * @date 2023/03/13
 */
@RestController
@RequestMapping("/web/database")
@Api(value = "數(shù)據(jù)庫管理")
public class WebDatabaseController {
    /**
     * 分頁列表
     *
     * @param request
     * @return
     */
    @PostMapping("/page")
    @ApiOperation(value = "數(shù)據(jù)庫管理-分頁列表")
    public ScmResponse<ScmPage<DatabaseDto>> page(@RequestBody DatabaseRequest request) {
        return ScmResponseUtil.success();
    }
}

可以看到通過javadoc自動生成了swagger注解,尤其是對于我們這樣微服務拆分很細的,應用非常多,接口更是多的,通過這種方式效率最高的

接口文檔

服務器啟動就可以把 接口應用名稱,接口URL地址,接口請求方式,接口描述,接口請求結構,接口響應結構 數(shù)據(jù)收集進行注冊自動生成接口文檔

接口擴展

1,數(shù)據(jù)脫敏

2,操作日志

3,防重復提交

4,接口冪等

5,接口限流

6,黑白名單

7,權限控制

8,。。。。。

到此這篇關于利用javadoc注釋自動生成Swagger注解的文章就介紹到這了,更多相關javadoc生成Swagger注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java父線程(或是主線程)等待所有子線程退出的實例

    Java父線程(或是主線程)等待所有子線程退出的實例

    下面小編就為大家分享一篇Java父線程(或是主線程)等待所有子線程退出的實例,具有很好的參考價值,希望對大家有所幫助
    2017-11-11
  • 使用通過ARP類似P2P終結者實現(xiàn)數(shù)據(jù)封包

    使用通過ARP類似P2P終結者實現(xiàn)數(shù)據(jù)封包

    目前網(wǎng)絡上類似P2P終結者這類軟件,主要都是基于ARP欺騙實現(xiàn)的,網(wǎng)絡上到處都有關于ARP的介紹,不過為了本文讀者不需要再去查找,我就在這里大概講解一下
    2012-12-12
  • java異常和錯誤類總結(必看篇)

    java異常和錯誤類總結(必看篇)

    下面小編就為大家?guī)硪黄猨ava異常和錯誤類總結(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • Java Stream 流的使用過程解析

    Java Stream 流的使用過程解析

    這篇文章主要介紹了Java Stream 流的使用過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Java字符串格式化,{}占位符根據(jù)名字替換實例

    Java字符串格式化,{}占位符根據(jù)名字替換實例

    這篇文章主要介紹了Java字符串格式化,{}占位符根據(jù)名字替換實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 確保SpringBoot定時任務只執(zhí)行一次的常見方法小結

    確保SpringBoot定時任務只執(zhí)行一次的常見方法小結

    在Spring Boot項目中,確保定時任務只執(zhí)行一次是一個常見的需求,這種需求可以通過多種方式來實現(xiàn),以下是一些常見的方法,它們各具特點,可以根據(jù)項目的實際需求來選擇最合適的方法,需要的朋友可以參考下
    2024-10-10
  • 詳解Java設計模式之職責鏈模式

    詳解Java設計模式之職責鏈模式

    責任鏈模式是一種行為設計模式,使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關系,文中通過代碼示例給大家介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • java返回的List進行add操作報錯

    java返回的List進行add操作報錯

    本文主要介紹了java返回的List進行add操作報錯,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • Hibernate核心思想與接口簡介

    Hibernate核心思想與接口簡介

    這篇文章主要介紹了Hibernate核心思想與接口的相關內(nèi)容,需要的朋友可以參考下。
    2017-09-09
  • SpringBoot和MyBatis環(huán)境下實現(xiàn)動態(tài)數(shù)據(jù)源切換過程

    SpringBoot和MyBatis環(huán)境下實現(xiàn)動態(tài)數(shù)據(jù)源切換過程

    dynamic-datasource-spring-boot-starter?是一個用于在SpringBoot和MyBatis環(huán)境下實現(xiàn)動態(tài)數(shù)據(jù)源切換的工具,它簡化了配置和切換邏輯,通過引入依賴,配置數(shù)據(jù)源和使用@DS注解,可以輕松實現(xiàn)數(shù)據(jù)源的動態(tài)切換
    2025-10-10

最新評論

沈阳市| 南涧| 阿鲁科尔沁旗| 沭阳县| 怀化市| 乌审旗| 山东省| 盘山县| 东乡县| 崇阳县| 花垣县| 仁寿县| 万州区| 镇安县| 汉沽区| 平果县| 栖霞市| 任丘市| 麻栗坡县| 潞西市| 许昌市| 奈曼旗| 古浪县| 通许县| 衡阳市| 宁河县| 马关县| 池州市| 晋宁县| 金山区| 遵化市| 牟定县| 阿鲁科尔沁旗| 张家口市| 呼图壁县| 小金县| 永州市| 泰州市| 洛阳市| 临城县| 灵山县|