Everit JSON Schema校验如何正确解引用独立JSON的$ref引用
问题原因
everit json-schema 加载器默认遇到$ref时,会按引用地址拉取对应资源(本地路径/网络地址)。当前代码连续调用.schemaJson()的写法无效:该方法每次调用都会覆盖之前设置的主schema,不会把传入的schema加入可解析的引用注册表。加载主schema遇到someRefSchema.json引用时,仍会尝试访问https://test.com/someRefSchema.json拉取资源,因此抛出文件找不到异常。单独配置resolutionScope仅能设置相对引用的解析根路径,不会将本地持有的referenceSchema注册到解析表中,无法解决问题。
修复方案
不要重复调用.schemaJson(),改用registerSchema()方法,提前将被引用的独立schema按其$id值注册到加载器中,加载时遇到对应$ref会直接从注册表读取,不会发起远程请求。
修正后的加载代码:
// 转换两个schema为JSONObject对象 JSONObject mainSchemaObj = new JSONObject(schema); JSONObject refSchemaObj = new JSONObject(referenceSchema); Schema schemaTarget = SchemaLoader.builder() .draftV7Support() .resolutionScope("https://test.com/") // 注册被引用schema,key与schema内$id字段完全一致 .registerSchema("https://test.com/someRefSchema.json", refSchemaObj) // 仅调用一次schemaJson设置主加载目标 .schemaJson(mainSchemaObj) .build() .load() .build(); // 原有校验逻辑保持不变 try { schemaTarget.validate(new JSONObject(subject)); } catch (ValidationException e) { throw new ValidationException(schema, "Error occurred: " + e.getMessage(), e.getKeyword(), e.getSchemaLocation()); }
注意事项
- 注册被引用schema时,传入的id字符串必须和对应schema内的
$id字段值完全匹配,否则会匹配失败,继续走远程拉取逻辑 - 存在多个独立被引用schema时,可多次调用
registerSchema逐一注册 - 主schema仅需调用一次
.schemaJson()传入,重复调用会覆盖之前的配置,导致加载逻辑错误
内容的提问来源于stack exchange,提问作者N1kk1
相关产品推荐
相关产品推荐

