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

利用javadoc注釋自動(dòng)生成Swagger注解

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

目的

可視化接口管理平臺(tái),通過(guò)接口管理平臺(tái)一目了然知道接口的作用,接口上面擴(kuò)展了哪些功能,從而做到對(duì)應(yīng)用程序代碼零侵入

現(xiàn)狀

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

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

思路

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

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

3,使用開(kāi)源的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;
/**
 * 通過(guò)javadoc注釋自動(dòng)生成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(), "項(xiàng)目路徑不存在");
        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(), "項(xiàng)目路徑不存在");
        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ù)庫(kù)管理
 *
 * @author xiongyan
 * @date 2023/03/13
 */
@RestController
@RequestMapping("/web/database")
public class WebDatabaseController {
    /**
     * 分頁(yè)列表
     *
     * @param request
     * @return
     */
    @PostMapping("/page")
    public ScmResponse<ScmPage<DatabaseDto>> page(@RequestBody DatabaseRequest request) {
        return ScmResponseUtil.success();
    }
}
/**
 * 數(shù)據(jù)庫(kù)管理
 *
 * @author xiongyan
 * @date 2023/03/13
 */
@RestController
@RequestMapping("/web/database")
@Api(value = "數(shù)據(jù)庫(kù)管理")
public class WebDatabaseController {
    /**
     * 分頁(yè)列表
     *
     * @param request
     * @return
     */
    @PostMapping("/page")
    @ApiOperation(value = "數(shù)據(jù)庫(kù)管理-分頁(yè)列表")
    public ScmResponse<ScmPage<DatabaseDto>> page(@RequestBody DatabaseRequest request) {
        return ScmResponseUtil.success();
    }
}

可以看到通過(guò)javadoc自動(dòng)生成了swagger注解,尤其是對(duì)于我們這樣微服務(wù)拆分很細(xì)的,應(yīng)用非常多,接口更是多的,通過(guò)這種方式效率最高的

接口文檔

服務(wù)器啟動(dòng)就可以把 接口應(yīng)用名稱,接口URL地址,接口請(qǐng)求方式,接口描述,接口請(qǐng)求結(jié)構(gòu),接口響應(yīng)結(jié)構(gòu) 數(shù)據(jù)收集進(jìn)行注冊(cè)自動(dòng)生成接口文檔

接口擴(kuò)展

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

2,操作日志

3,防重復(fù)提交

4,接口冪等

5,接口限流

6,黑白名單

7,權(quán)限控制

8,。。。。。

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

相關(guān)文章

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

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

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

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

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

    java異常和錯(cuò)誤類總結(jié)(必看篇)

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

    Java Stream 流的使用過(guò)程解析

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

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

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

    確保SpringBoot定時(shí)任務(wù)只執(zhí)行一次的常見(jiàn)方法小結(jié)

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

    詳解Java設(shè)計(jì)模式之職責(zé)鏈模式

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

    java返回的List進(jìn)行add操作報(bào)錯(cuò)

    本文主要介紹了java返回的List進(jìn)行add操作報(bào)錯(cuò),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Hibernate核心思想與接口簡(jiǎn)介

    Hibernate核心思想與接口簡(jiǎn)介

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

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

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

最新評(píng)論

邛崃市| 高邮市| 长垣县| 兴城市| 太谷县| 淳化县| 竹溪县| 沛县| 定南县| 沙湾县| 陆河县| 霍林郭勒市| 姚安县| 东源县| 南靖县| 呼图壁县| 凤庆县| 明光市| 天全县| 阿图什市| 始兴县| 特克斯县| 琼中| 建瓯市| 都匀市| 普定县| 兰溪市| 台南县| 彩票| 盐源县| 天水市| 辽阳县| 柘荣县| 准格尔旗| 虹口区| 秀山| 泰宁县| 邵阳县| 平顺县| 新巴尔虎右旗| 宁津县|