如何为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
相关产品推荐
相关产品推荐

