利用javadoc注释自动生成Swagger注解

 更新时间:2023年08月13日 09:20:50   作者:三火哥  
由于现在controller方法上面没有swagger注解,只能拿到接口url地址,无法获得接口功能描述,所以本文为大家介绍一下如何利用javadoc注释自动生成Swagger注解,感兴趣的可以了解下

目的

可视化接口管理平台,通过接口管理平台一目了然知道接口的作用,接口上面扩展了哪些功能,从而做到对应用程序代码零侵入

现状

由于现在controller方法上面没有swagger注解,只能拿到接口url地址,无法获得接口功能描述。

值得庆幸的是我们的代码非常规范每个方法都有标准的javadoc注释,于是就想到了获取javadoc注释的描述自动生成swagger注解

思路

1,AOP切面,你会发现根本无法获取javadoc,这个方案就直接pass掉了

2,读文件流获取文件内容解析出想要的数据,虽然可以但是费时费力,不是最优的方案

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;
    }
}

效果

/**
 * 数据库管理
 *
 * @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();
    }
}
/**
 * 数据库管理
 *
 * @author xiongyan
 * @date 2023/03/13
 */
@RestController
@RequestMapping("/web/database")
@Api(value = "数据库管理")
public class WebDatabaseController {
    /**
     * 分页列表
     *
     * @param request
     * @return
     */
    @PostMapping("/page")
    @ApiOperation(value = "数据库管理-分页列表")
    public ScmResponse<ScmPage<DatabaseDto>> page(@RequestBody DatabaseRequest request) {
        return ScmResponseUtil.success();
    }
}

可以看到通过javadoc自动生成了swagger注解,尤其是对于我们这样微服务拆分很细的,应用非常多,接口更是多的,通过这种方式效率最高的

接口文档

服务器启动就可以把 接口应用名称,接口URL地址,接口请求方式,接口描述,接口请求结构,接口响应结构 数据收集进行注册自动生成接口文档

接口扩展

1,数据脱敏

2,操作日志

3,防重复提交

4,接口幂等

5,接口限流

6,黑白名单

7,权限控制

8,。。。。。

到此这篇关于利用javadoc注释自动生成Swagger注解的文章就介绍到这了,更多相关javadoc生成Swagger注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解java中的synchronized关键字

    详解java中的synchronized关键字

    这篇文章主要介绍了java中的synchronized关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • Java 栈和队列的交互实现

    Java 栈和队列的交互实现

    栈和队列都是常用的数据结构,本文就来介绍一下Java 栈和队列的交互实现,主要包括队列模拟实现栈及栈模拟实现队列,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • SpringBoot整合Mybatis简单实现增删改查

    SpringBoot整合Mybatis简单实现增删改查

    这篇文章主要介绍了SpringBoot整合Mybatis简单实现增删改查,文章为围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • 自定义log4j.properties的加载位置方式

    自定义log4j.properties的加载位置方式

    这篇文章主要介绍了自定义log4j.properties的加载位置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 利用SpringDataJPA开启审计功能,自动保存操作人操作时间

    利用SpringDataJPA开启审计功能,自动保存操作人操作时间

    这篇文章主要介绍了利用SpringDataJPA开启审计功能,自动保存操作人操作时间,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java SPI机制详细介绍

    Java SPI机制详细介绍

    大家好,本篇文章主要讲的是Java SPI机制详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • java判断回文数示例分享

    java判断回文数示例分享

    这篇文章主要介绍了java判断回文数示例,需要的朋友可以参考下
    2014-03-03
  • springboot整合springsecurity与mybatis-plus的简单实现

    springboot整合springsecurity与mybatis-plus的简单实现

    Spring Security基于Spring开发,项目中如果使用Spring作为基础,配合Spring Security做权限更加方便,而Shiro需要和Spring进行整合开发。因此作为spring全家桶中的Spring Security在java领域很常用
    2021-10-10
  • 关于SpringBoot整合RabbitMQ实现死信队列

    关于SpringBoot整合RabbitMQ实现死信队列

    这篇文章主要介绍了关于SpringBoot整合RabbitMQ实现死信队列,死信队列实际上就是一个普通的队列,只是这个队列跟死信交换机进行了绑定,用来存放死信而已,需要的朋友可以参考下
    2023-05-05
  • springboot高并发下提高吞吐量的实现

    springboot高并发下提高吞吐量的实现

    这篇文章主要介绍了springboot高并发下提高吞吐量的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11

最新评论