如何使用Java从swagger.yaml提取路径、对应响应码及引用路径
现有资源
swagger.yaml 配置文件内容
swagger: "2.0" info: description: "This is a sample server Petstore server" version: 1.0.0 title: Swagger Petstore YAML termsOfService: "http://swagger.io/terms/" contact: email: "apiteam@swagger.io" license: name: Apache 2.0 url: "http://www.apache.org/licenses/LICENSE-2.0.html" paths: /pet: post: tags: - pet summary: Add a new pet to the store x-swagger-router-controller: SampleController description: "" operationId: addPet consumes: - application/json - application/xml produces: - application/xml - application/json parameters: - in: body name: body description: Pet object that needs to be added to the store required: false schema: $ref: "#/definitions/Pet" responses: "405": description: Invalid input schema: $ref: "#/definitions/Pet" security: - petstore_auth: - "write:pets" - "read:pets" put: tags: - pet summary: Update an existing pet description: "" operationId: updatePet consumes: - application/json - application/xml produces: - application/xml - application/json parameters: - in: body name: body description: Pet object that needs to be added to the store required: false schema: $ref: "#/definitions/Pet23" responses: "400": description: Invalid ID supplied schema: $ref: "#/definitions/Pet23"
原有Config类代码
package Configuration; import org.yaml.snakeyaml.Yaml; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; public class Config{ public static void main(String[] args) throws FileNotFoundException { Yaml yaml = new Yaml(); InputStream inputStream = new FileInputStream("swagger.yml"); System.out.println(inputStream); HashMap yamlMap = yaml.load(inputStream); for (Object o : yamlMap.entrySet()) { System.out.println(o); } HashMap Paths = (HashMap) yamlMap.get("Paths"); System.out.println(Paths); } }
需求说明
原有代码仅支持全量打印paths节点数据,需要实现以下解析能力:
- 提取所有接口路径(如
/pet) - 提取每个路径下各接口对应的HTTP响应码
- 提取并存储每个路径、响应关联的schema引用路径
实现方案
首先修正原代码的基础问题:YAML键名大小写敏感,原代码取节点时用了大写开头的"Paths",和文件中实际的小写"paths"键不匹配,会直接取到空值。
以下是可直接运行的完整实现代码,逐层解析嵌套的YAML结构,将需要的字段结构化存储:
package Configuration; import org.yaml.snakeyaml.Yaml; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.*; public class Config { // 结构化存储解析结果:key为接口路径,value为该路径下各HTTP方法的解析数据 static Map<String, Map<String, Object>> apiParseResult = new HashMap<>(); public static void main(String[] args) throws FileNotFoundException { Yaml yaml = new Yaml(); InputStream inputStream = new FileInputStream("swagger.yml"); Map<String, Object> yamlMap = yaml.load(inputStream); // 读取小写的paths节点 Map<String, Object> pathsMap = (Map<String, Object>) yamlMap.get("paths"); if (pathsMap == null) { System.out.println("yaml文件中未找到paths节点"); return; } // 遍历每个接口路径 for (Map.Entry<String, Object> pathEntry : pathsMap.entrySet()) { String path = pathEntry.getKey(); Map<String, Object> httpMethodMap = (Map<String, Object>) pathEntry.getValue(); Map<String, Object> methodInfo = new HashMap<>(); // 遍历该路径下的所有HTTP方法(get/post/put/delete等) for (Map.Entry<String, Object> methodEntry : httpMethodMap.entrySet()) { String httpMethod = methodEntry.getKey(); Map<String, Object> methodContent = (Map<String, Object>) methodEntry.getValue(); Map<String, Object> methodDetail = new HashMap<>(); // 提取请求体关联的schema引用 List<Map<String, Object>> parameters = (List<Map<String, Object>>) methodContent.get("parameters"); if (parameters != null) { List<String> paramSchemaRefs = new ArrayList<>(); for (Map<String, Object> param : parameters) { Map<String, Object> schema = (Map<String, Object>) param.get("schema"); if (schema != null && schema.get("$ref") != null) { paramSchemaRefs.add(schema.get("$ref").toString()); } } methodDetail.put("requestSchemaRefs", paramSchemaRefs); } // 提取响应码和对应schema引用 Map<String, Object> responsesMap = (Map<String, Object>) methodContent.get("responses"); Map<String, String> responseRefMap = new HashMap<>(); if (responsesMap != null) { for (Map.Entry<String, Object> responseEntry : responsesMap.entrySet()) { String responseCode = responseEntry.getKey(); Map<String, Object> responseContent = (Map<String, Object>) responseEntry.getValue(); Map<String, Object> resSchema = (Map<String, Object>) responseContent.get("schema"); if (resSchema != null && resSchema.get("$ref") != null) { responseRefMap.put(responseCode, resSchema.get("$ref").toString()); } else { responseRefMap.put(responseCode, null); } } } methodDetail.put("responseSchemaRefs", responseRefMap); methodInfo.put(httpMethod, methodDetail); } apiParseResult.put(path, methodInfo); } // 打印解析结果验证 for (Map.Entry<String, Map<String, Object>> pathRes : apiParseResult.entrySet()) { System.out.println("接口路径:" + pathRes.getKey()); Map<String, Object> methods = pathRes.getValue(); for (Map.Entry<String, Object> methodRes : methods.entrySet()) { System.out.println(" HTTP方法:" + methodRes.getKey().toUpperCase()); Map<String, Object> detail = (Map<String, Object>) methodRes.getValue(); System.out.println(" 请求schema引用:" + detail.get("requestSchemaRefs")); System.out.println(" 响应码&对应schema引用:" + detail.get("responseSchemaRefs")); } System.out.println("----------------------------------------"); } } }
运行后输出结果示例:
接口路径:/pet HTTP方法:POST 请求schema引用:[#/definitions/Pet] 响应码&对应schema引用:{405=#/definitions/Pet} HTTP方法:PUT 请求schema引用:[#/definitions/Pet23] 响应码&对应schema引用:{400=#/definitions/Pet23} ----------------------------------------
解析后所有数据都存在静态变量apiParseResult中,可以直接按路径、HTTP方法维度取需要的schema引用和响应码数据。
内容的提问来源于stack exchange,提问作者Yarasu Lavanya
相关产品推荐
相关产品推荐

