利用javadoc注釋自動生成Swagger注解
目的
可視化接口管理平臺,通過接口管理平臺一目了然知道接口的作用,接口上面擴展了哪些功能,從而做到對應(yīng)用程序代碼零侵入
現(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注解,尤其是對于我們這樣微服務(wù)拆分很細的,應(yīng)用非常多,接口更是多的,通過這種方式效率最高的
接口文檔
服務(wù)器啟動就可以把 接口應(yīng)用名稱,接口URL地址,接口請求方式,接口描述,接口請求結(jié)構(gòu),接口響應(yīng)結(jié)構(gòu) 數(shù)據(jù)收集進行注冊自動生成接口文檔
接口擴展
1,數(shù)據(jù)脫敏
2,操作日志
3,防重復(fù)提交
4,接口冪等
5,接口限流
6,黑白名單
7,權(quán)限控制
8,。。。。。
到此這篇關(guān)于利用javadoc注釋自動生成Swagger注解的文章就介紹到這了,更多相關(guān)javadoc生成Swagger注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合Mybatis簡單實現(xiàn)增刪改查
這篇文章主要介紹了SpringBoot整合Mybatis簡單實現(xiàn)增刪改查,文章為圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08利用SpringDataJPA開啟審計功能,自動保存操作人操作時間
這篇文章主要介紹了利用SpringDataJPA開啟審計功能,自動保存操作人操作時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12springboot整合springsecurity與mybatis-plus的簡單實現(xiàn)
Spring Security基于Spring開發(fā),項目中如果使用Spring作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進行整合開發(fā)。因此作為spring全家桶中的Spring Security在java領(lǐng)域很常用2021-10-10關(guān)于SpringBoot整合RabbitMQ實現(xiàn)死信隊列
這篇文章主要介紹了關(guān)于SpringBoot整合RabbitMQ實現(xiàn)死信隊列,死信隊列實際上就是一個普通的隊列,只是這個隊列跟死信交換機進行了綁定,用來存放死信而已,需要的朋友可以參考下2023-05-05springboot高并發(fā)下提高吞吐量的實現(xiàn)
這篇文章主要介紹了springboot高并發(fā)下提高吞吐量的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11