如何在swagger-parser 2.1.6中仅解析内部$ref禁用外部引用?
解决Swagger-Parser 2.1.6限制外部$ref解析的最优方案
核心思路
利用Swagger-Parser的SchemaResolver扩展能力,自定义引用解析逻辑,只允许解析内部本地引用(即#/开头的引用),直接拦截外部文件或网络引用,无需预处理遍历修改schema。
具体实现步骤
1. 自定义SchemaResolver
继承默认的SchemaResolver,重写resolveRef方法,判断引用是否为内部引用:
import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.core.resolvers.SchemaResolver; import io.swagger.v3.parser.models.RefFormat; import io.swagger.v3.parser.util.RefUtils; public class RestrictedSchemaResolver extends SchemaResolver { public RestrictedSchemaResolver(ParseOptions options) { super(options); } @Override protected String resolveRef(String ref, String location, RefFormat refFormat) { // 仅处理内部引用(以#/开头) if (ref.startsWith("#/")) { return super.resolveRef(ref, location, refFormat); } // 外部引用直接返回null,阻止解析 return null; } }
2. 替换默认Resolver并解析Schema
创建OpenAPIParser实例时,注入自定义的RestrictedSchemaResolver,开启引用解析但通过自定义逻辑过滤外部引用:
import io.swagger.v3.parser.OpenAPIParser; import io.swagger.v3.parser.core.models.SwaggerParseResult; public class OpenApiParserExample { public static void main(String[] args) { ParseOptions options = new ParseOptions(); options.setResolve(true); // 开启引用解析 OpenAPIParser parser = new OpenAPIParser(); // 替换默认的SchemaResolver为自定义实现 parser.setSchemaResolver(new RestrictedSchemaResolver(options)); String specPath = "path/to/your/openapi.yaml"; SwaggerParseResult result = parser.readLocation(specPath, null, options); // 处理解析结果 if (result.getOpenAPI() != null) { System.out.println("Schema解析成功"); } else { System.err.println("解析错误: " + result.getMessages()); } } }
方案优势
- 无需预处理遍历修改原始schema,避免手动遍历可能出现的遗漏或格式错误
- 直接在解析阶段拦截外部引用,逻辑更精准,性能更优
- 保留Swagger-Parser原生的内部引用解析能力,兼容所有合法的内部
$ref格式
补充说明
如果需要更精细的控制(比如允许特定本地文件但阻止网络引用),可以在resolveRef方法中扩展判断逻辑,例如:
- 区分
RefFormat.LOCAL和RefFormat.REMOTE,只允许本地内部引用 - 对本地文件引用额外判断是否在指定目录范围内
内容的提问来源于stack exchange,提问作者Fabian Geitner
相关产品推荐
相关产品推荐

