Spring Boot中JSON Schema跨子Schema条件验证异常排查
排查JSON Schema条件验证失效问题
1. $ref引用的作用域冲突
用$ref引用子Schema时,$ref会完全替换当前位置的所有关键字,包括if/then这类条件判断。如果你的条件逻辑写在$ref外部,或者$ref覆盖了条件的上下文,会导致条件无法关联到type-emp-land.location字段。
- 典型错误:主Schema直接
$ref: sub1.json,然后在主Schema根节点写if判断,此时if的上下文是主Schema根,而非sub1里的字段路径,自然找不到目标字段。 - 修正思路:把条件判断和目标字段放在同一个Schema上下文,或者用Draft 2020-12的
$dynamicRef/$dynamicAnchor维持引用后的上下文关联。
2. 字段路径写错了
条件判断里的字段路径必须精准,尤其是嵌套字段和带连字符的字段:
- 错误示例:
if: { properties: { location: { const: "OutTown" } } },但location实际在type-emp-land对象下,正确路径应该是properties: { "type-emp-land": { properties: { location: { const: "OutTown" } } } }。 - 注意带连字符的字段名(比如
type-emp-land)必须用引号包裹,否则会被解析成无效语法。
3. 验证器版本对Draft 2020-12支持不足
com.networknt json-schema-validator 1.4.0是2020年的版本,而Draft 2020-12是同年后期推出的,部分特性(比如$dynamicRef、条件判断的上下文处理)可能没完全实现。
- 直接升级到该库的最新稳定版(比如2.x系列),新版本对Draft 2020-12的支持更完整。
4. 条件规则的作用对象错误
如果sub2是通过$ref引入的,要确认then/else里的必填规则是否作用在sub2对象上:
- 错误示例:
then: { required: ["radius"] },这个规则是给主Schema根节点加的,不是sub2。正确写法是then: { properties: { sub2: { required: ["radius"] } } },确保必填规则指向sub2里的radius字段。
5. 验证器未启用Draft 2020-12规范
初始化验证器时必须明确指定使用Draft 2020-12,否则默认用旧版本(比如Draft 7),条件特性不生效:
SchemaValidatorsConfig config = new SchemaValidatorsConfig(); config.setSpecVersion(SpecVersion.VersionFlag.V202012); JsonSchema schema = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012).getSchema(schemaContent, config);
- 检查代码里有没有正确设置
SpecVersion.V202012,没设置的话验证器会忽略Draft 2020-12的特性。
内容的提问来源于stack exchange,提问作者Arun
相关产品推荐
相关产品推荐

