手打不易,如果转摘,请注明出处!
注明原文: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 test
version: '1.0'
host: 'localhost'
basePath: /test
schemes:
- "https"
tags:
- name: TestManage
description: 测试管理
paths:
/some/ping:
get:
tags:
- TestManage
operationId: pingGet
description: 一个测试方法
parameters:
- name: i
in: body
description: query字段
required: true
schema:
$ref: './swagger/swagger-reference.yaml#/type'
responses:
'201':
description: OK
/some/ping2:
post:
tags:
- TestManage
operationId: pingPost
description: 一个测试方法2
parameters:
- name: num
in: query
description: 数量
required: true
type: integer
format: int32
responses:
'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 path
String path = entry.getKey();
// api
PathItem pathItem = entry.getValue();
Operation api = getOperation(pathItem);
// request type
PathItem.HttpMethod method = getMethod(pathItem);
// operationId
String 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()) {
// 递归xml
getFileList(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 中都可以!