手打不易,如果转摘,请注明出处!
注明原文:https://zhangxiaofan.blog.csdn.net/article/details/129167371
目录
前言
官方文档
项目配置
示例代码
测试文件
解析代码
运行结果
前言
用到这个工具是因为项目需要,本身项目比较多,swagger.yaml也很多,公司的管理平台无法直观的统计全部服务的yaml中的API,因此就用这个工具快速提取我们各个项目中的API信息,包括API名称、操作类型、请求类型等等。
官方文档
swagger-api 的使用官方文档:
https://github.com/swagger-api/swagger-parser
项目配置
pom.xml :
<dependency><groupId>io.swagger.parser.v3</groupId><artifactId>swagger-parser</artifactId><version>2.1.12</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.3</version></dependency>
示例代码
测试文件
测试文件名:
swagger-test1.yaml
swagger-test2.yaml
测试文件目录:
src/main/resources/swagger/test
第1个swagger文件:
src/main/resources/swagger/test/service1/swagger-test1.yaml
第2个swagger文件:
src/main/resources/swagger/test/service2/swagger-test2.yaml
测试文件内容(方便测试,两个都是一样的):
swagger: '2.0'
info:title: ping testversion: '1.0'
host: 'localhost'
basePath: /test
schemes:- "https"
tags:- name: TestManagedescription: 测试管理
paths:/some/ping:get:tags:- TestManageoperationId: pingGetdescription: 一个测试方法parameters:- name: iin: bodydescription: query字段required: trueschema:$ref: './swagger/swagger-reference.yaml#/type'responses:'201':description: OK/some/ping2:post:tags:- TestManageoperationId: pingPostdescription: 一个测试方法2parameters:- name: numin: querydescription: 数量required: truetype: integerformat: int32responses:'201':description: OK
解析代码
package util;import cn.hutool.core.util.ObjectUtil;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.parser.core.models.ParseOptions;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import lombok.extern.slf4j.Slf4j;import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;@Slf4j
public enum SwaggerParseUtl {;/*** 待解析的文件目录*/private static final String RESOURCE_DIRECTORY = "E:\\JavaProject\\local\\JavaCoreTest\\src\\main\\resources\\swagger\\test";public static void main(String[] args) {List<String> fileList = new ArrayList<>();// 读取所有的 yaml 文件getFileList(RESOURCE_DIRECTORY, ".yaml", fileList);// 依次解析 yaml 文件for (String file : fileList) {String[] split = file.replace("\\", "/").split("/");// 文件名String fileName = split[split.length - 1];// 这里的 swagger.yaml 按服务名存放String serviceName = split[split.length - 2];parseSwaggerYaml("swagger/test", serviceName, fileName);}}/*** 解析方法** @param resourceRelativePath 目标文件在 resources 下的相对路径* @param serviceName 服务名* @param fileName 文件*/public static void parseSwaggerYaml(String resourceRelativePath, String serviceName, String fileName) {String filePath = resourceRelativePath + "/" + serviceName + "/" + fileName;ParseOptions options = new ParseOptions();options.setResolve(true);SwaggerParseResult result = new OpenAPIParser().readLocation(filePath, null, options);OpenAPI openAPI = result.getOpenAPI();Paths paths = openAPI.getPaths();for (Map.Entry<String, PathItem> entry : paths.entrySet()) {// url pathString path = entry.getKey();// apiPathItem pathItem = entry.getValue();Operation api = getOperation(pathItem);// request typePathItem.HttpMethod method = getMethod(pathItem);// operationIdString operationId = api.getOperationId();// 描述String description = "";if (!StringUtils.isEmpty(api.getDescription())) {description = api.getDescription();} else {description = api.getSummary();}String tag = "";if (!CollectionUtils.isEmpty(api.getTags())) {tag = api.getTags().get(0);}System.out.println(MessageFormat.format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", serviceName, fileName,method, path, tag, operationId, description));}}/*** 获取请求方法类型*/private static PathItem.HttpMethod getMethod(PathItem pathItem) {Operation api = null;if (!ObjectUtil.isEmpty(pathItem.getGet())) {return PathItem.HttpMethod.GET;} else if (!ObjectUtil.isEmpty(pathItem.getPost())) {return PathItem.HttpMethod.POST;} else if (!ObjectUtil.isEmpty(pathItem.getPut())) {return PathItem.HttpMethod.PUT;} else if (!ObjectUtil.isEmpty(pathItem.getDelete())) {return PathItem.HttpMethod.DELETE;} else if (!ObjectUtil.isEmpty(pathItem.getPatch())) {return PathItem.HttpMethod.PATCH;} else {throw new RuntimeException("不支持的请求类型");}}/*** 获取 Operation Api*/private static Operation getOperation(PathItem pathItem) {Operation api = null;if (!ObjectUtil.isEmpty(pathItem.getGet())) {api = pathItem.getGet();} else if (!ObjectUtil.isEmpty(pathItem.getPost())) {api = pathItem.getPost();} else if (!ObjectUtil.isEmpty(pathItem.getPut())) {api = pathItem.getPut();} else if (!ObjectUtil.isEmpty(pathItem.getDelete())) {api = pathItem.getDelete();} else if (!ObjectUtil.isEmpty(pathItem.getPatch())) {api = pathItem.getPatch();} else {throw new RuntimeException("不支持的请求类型");}return api;}/*** 递归遍历所有文件** @param filePath 文件路径* @param suffix 指定的文件格式* @param fileList 获取的文件list*/private static List<String> getFileList(String filePath, String suffix, List<String> fileList) {File root = new File(filePath);// 非目录if (!root.isDirectory()) {fileList.add(root.getAbsolutePath());return fileList;}// 目录则递归遍历File[] files = root.listFiles();if (null != files) {for (File file : files) {if (file.isDirectory()) {// 递归xmlgetFileList(file.getAbsolutePath(), suffix, fileList);} else if (file.getName().contains(suffix)) {fileList.add(file.getAbsolutePath());}}}return fileList;}
}
运行结果
Connected to the target VM, address: '127.0.0.1:3983', transport: 'socket'
service1 swagger-test1.yaml GET /some/ping TestManage pingGet 一个测试方法
service1 swagger-test1.yaml POST /some/ping2 TestManage pingPost 一个测试方法2
service2 swagger-test2.yaml GET /some/ping TestManage pingGet 一个测试方法
service2 swagger-test2.yaml POST /some/ping2 TestManage pingPost 一个测试方法2
Disconnected from the target VM, address: '127.0.0.1:3983', transport: 'socket'Process finished with exit code 0
后面可以直接复制这个结果到 excel 编辑,或者用 Java 代码直接写到 excel 中都可以!