networknt JSON Schema校验器$id与$ref引用外部schema文件失效问题求助
networknt JSON Schema校验器跨文件$ref引用异常解决方法
问题根因
networknt JSON Schema Validator的默认引用解析逻辑为:当遇到未知URI的$ref引用时,会尝试将URI作为真实网络地址发起请求拉取Schema资源,这就是你出现FileNotFoundException的原因,并非JSON Schema规范要求$id必须可网络访问,只是你未提前将公共Schema注册到校验器的Schema缓存中。
前置修正
你提供的示例Schema中$id存在明显格式错误:https://example.com /schema/xxx里example.com后多了一个空格,会导致URI匹配失败,需要先删除所有$id和$ref里的多余空格,保证所有引用的URI和对应Schema的$id取值完全一致。
解决步骤
通过JsonSchemaFactory的registerSchema方法预注册所有公共Schema到校验器缓存中,校验器遇到对应$ref时会优先从缓存查找,不会发起网络请求。
完整示例代码
import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.InputStream; import java.net.URI; public class SchemaValidateDemo { public static void main(String[] args) throws Exception { // 初始化适配Draft 07版本的Schema工厂 JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7); ObjectMapper objectMapper = new ObjectMapper(); // 1. 预注册公共通用Schema // 读取项目resource目录下的公共Schema文件 InputStream commonSchemaStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("common_json_schema_defs.json"); JsonNode commonSchemaNode = objectMapper.readTree(commonSchemaStream); // 注册时的URI必须和公共Schema的$id取值完全一致 schemaFactory.registerSchema( new URI("https://example.com/schema/common/common_json_schema_defs.json"), commonSchemaNode ); // 2. 加载业务Schema InputStream businessSchemaStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("request_schema.json"); JsonNode businessSchemaNode = objectMapper.readTree(businessSchemaStream); JsonSchema businessSchema = schemaFactory.getSchema(businessSchemaNode); // 3. 执行业务数据校验 JsonNode businessData = objectMapper.readTree("待校验的业务JSON字符串"); var errors = businessSchema.validate(businessData); if (errors.isEmpty()) { System.out.println("数据校验通过"); } else { errors.forEach(error -> System.out.println("校验错误:" + error.getMessage())); } } }
注意事项
- 所有被外部引用的Schema都需要提前注册到
JsonSchemaFactory中,注册用的URI必须和对应Schema的$id完全匹配,包括大小写、路径、尾斜杠等细节 - 项目存在多个公共Schema时,可以在项目启动阶段一次性完成所有公共Schema的注册,避免重复注册
- 你也可以将$id设置为
classpath:协议的路径,比如$id: "classpath:schema/common/common_json_schema_defs.json",networknt默认支持classpath资源拉取,这种情况下不需要额外注册也能自动识别到项目resource下的对应Schema文件
内容的提问来源于stack exchange,提问作者palwe-prafulla
相关产品推荐
相关产品推荐

