You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为json-schema添加severity属性并通过networknt校验器获取该值

如何在networknt JSON Schema Validator中获取自定义校验级别并输出对应日志

1. 调整Schema结构并配置校验器忽略未知关键字

首先,你的Schema可以保留自定义的severity和message字段,但需要让校验器忽略这些非标准JSON Schema关键字,避免加载Schema时报错。

单级别配置示例Schema:

{
  "type": "object",
  "properties": {
    "zip_code": {
      "type": "string",
      "minLength": 1,
      "severity": "Error",
      "message": {
        "type": "Address.zip_code is not a 'String' value",
        "minLength": "Address.zip_code is empty"
      }
    }
  }
}

按校验规则单独配置级别示例:

"zip_code": {
  "type": "string",
  "minLength": 1,
  "severity": {
    "type": "Error",
    "minLength": "Warning"
  },
  "message": {
    "type": "Address.zip_code is not a 'String' value",
    "minLength": "Address.zip_code is empty"
  }
}

2. Java实现代码

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.Set;

public class SchemaValidator {
    private static final Logger log = LoggerFactory.getLogger(SchemaValidator.class);
    private static final ObjectMapper mapper = new ObjectMapper();

    public static void validatePayload(InputStream schemaStream, JsonNode event) {
        try {
            // 读取Schema为JsonNode,保留引用方便后续获取自定义属性
            JsonNode schemaNode = mapper.readTree(schemaStream);
            
            // 创建校验器,配置忽略未知关键字
            JsonSchemaFactory factory = JsonSchemaFactory.builder(SpecVersion.VersionFlag.V202012)
                    .ignoreUnknownKeywords(true)
                    .build();
            JsonSchema jsonSchema = factory.getSchema(schemaNode);
            
            // 执行校验
            Set<ValidationMessage> validationMessages = jsonSchema.validate(event);
            
            // 处理每个校验结果,根据自定义级别输出日志
            for (ValidationMessage msg : validationMessages) {
                String propertyPath = msg.getPath();
                String keyword = msg.getKeyword();
                
                // 定位到Schema中对应的属性节点
                JsonNode propertyNode = getPropertyNode(schemaNode, propertyPath);
                if (propertyNode == null) {
                    log.warn(msg.getMessage());
                    continue;
                }
                
                // 获取自定义级别
                String severity = getSeverity(propertyNode, keyword);
                // 获取自定义错误信息
                String errorMessage = getCustomMessage(propertyNode, keyword, msg.getMessage());
                
                // 根据级别输出日志
                if ("Error".equalsIgnoreCase(severity)) {
                    log.error(errorMessage);
                } else {
                    log.warn(errorMessage);
                }
            }
        } catch (Exception e) {
            log.error("Schema validation failed due to unexpected error", e);
        }
    }

    /**
     * 根据属性路径从Schema节点中定位到对应的属性配置节点
     */
    private static JsonNode getPropertyNode(JsonNode schemaNode, String path) {
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        String[] pathParts = path.split("/");
        JsonNode currentNode = schemaNode.get("properties");
        
        for (String part : pathParts) {
            if (currentNode == null || !currentNode.has(part)) {
                return null;
            }
            currentNode = currentNode.get(part);
        }
        return currentNode;
    }

    /**
     * 获取自定义校验级别,支持全局级别或按关键字单独设置
     */
    private static String getSeverity(JsonNode propertyNode, String keyword) {
        // 优先读取按关键字设置的级别
        if (propertyNode.has("severity") && propertyNode.get("severity").isObject() 
                && propertyNode.get("severity").has(keyword)) {
            return propertyNode.get("severity").get(keyword).asText("Warning");
        }
        // 读取全局级别
        if (propertyNode.has("severity") && propertyNode.get("severity").isTextual()) {
            return propertyNode.get("severity").asText("Warning");
        }
        // 默认警告级别
        return "Warning";
    }

    /**
     * 获取自定义错误信息,没有则使用默认信息
     */
    private static String getCustomMessage(JsonNode propertyNode, String keyword, String defaultMsg) {
        if (propertyNode.has("message") && propertyNode.get("message").has(keyword)) {
            return propertyNode.get("message").get(keyword).asText(defaultMsg);
        }
        return defaultMsg;
    }
}

关键说明

  • 忽略未知关键字:通过JsonSchemaFactory.builder().ignoreUnknownKeywords(true)配置,确保自定义的severity和message不会被当作Schema错误。
  • 路径定位:利用ValidationMessage.getPath()获取校验失败的属性路径,再遍历Schema的properties节点找到对应属性的配置。
  • 灵活级别配置:支持给整个属性设置统一级别,也支持给每个校验规则(如type、minLength)单独设置级别。

内容的提问来源于stack exchange,提问作者Prasad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:57:16