如何为JSONSchema定制错误消息?

2022-08-17 00:00:00 jsonschema java json-schema-validator
有没有办法根据给定的条件提供自定义错误消息? 我使用的是https://github.com/networknt/json-schema-validator版本1.0.43

这是我的JSON架构:

{
  "$id": "https://configurations/provider.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Configuration",
  "type": "object",
  "properties": {
    "provider": {
      "description": "Name of the provider.",
      "enum": [
        "Provider #1",
        "Provider #2"
      ]
    },
    "configuration": {
      "$schema": "json-schema/configurations/configuration.json"
    }
  },
  "if": {
    "properties": {
      "parcsProvider": {
        "const": "Provider #1"
      }
    }
  },
  "then": {
    "required": [
      "configuration"
    ]
  },
  "else": {
    "not": {
      "required": [
        "configuration"
      ]
    }
  }
}
如果提供程序的值是";Provider#1";,则配置对象是必需的,如果它是";Provider#2";并且传递了配置,则会发生错误。我要自定义该错误,以便响应与现在相同,但使用像";Provider 2这样的自定义消息不能有配置。";

当前错误消息/响应:

{
    "timestamp": "2020-11-23T12:50:56.20658+01:00",
    "message": "invalid.json.input",
    "validationErrors": [
        {
            "field": "$",
            "message": "$: should not be valid to the schema "not" : {"required":["configuration"]}"
        }
    ]
}

解决方案

我有一个类似的要求要在我的一个项目中实现。对于验证,我使用https://github.com/everit-org/json-schema。

以下是我所做的

  1. 已对验证器抛出的所有类型的错误[必须有特定关键字]进行分类
  2. 现在,一旦拥有了所有密钥,您就可以轻松处理错误并发送自定义错误/响应。

以下是我为不同情况收集的钥匙,这可能会对您有所帮助-

MIN_LENGTH_VIOLATION = "expected minLength"
MAX_LENGTH_VIOLATION = "expected maxLength"
PATTERN_VIOLATION = "does not match pattern"
DATA_TYPE_VIOLATION = "expected type"
DEPENDENCY_VIOLATION = "is required"
FORMAT_VIOLATION_OR_ENUM_VALIDATION_VIOLATION = "is not a valid"
MANDATORY_FIELD_VIOLATION_OR_CONDITIONAL_VIOLATION = "required key"
NUMBER_IS_LESS_THAN_VIOLATION = "is not greater or equal to"
NUMBER_IS_GREATER_THAN_VIOLATION = "is not less or equal"
EXCLUSIVE_NUMBER_IS_GREATER_THAN_VIOLATION = "is not less than"
EXCLUSIVE_NUMBER_IS_LESS_THAN_VIOLATION = "is not greater than"
MULTIPLE_OF_VIOLATION = "is not a multiple"

示例代码-

 private static void validate(JSONObject request) {
    try {
        // Schema, that might be fetched dynamically from some data source
        JSONObject schema = new JSONObject();
        Schema loadedSchema = SchemaLoader.load(schema);
        loadedSchema.validate(request);
    } catch (ValidationException ve) {
        List<String> allErrorMessages = ve.getAllMessages();
        List<String> mandatoryFields = parseMandatoryField(allErrorMessages);
        if (CollectionUtils.isNotEmpty(mandatoryFields)) {
            throw new MandFieldMissingExp(mandatoryFields);
        } else {
            List<String> invalidFields = parseInvalids(allErrorMessages);
            throw new InvalidFieldExp(invalidFields);
        }
    }
}

private static List<String> parseMandatoryField(List<String> validationExceptionMessages) {
    Set<String> mandatoryListSet = new HashSet<>();
    validationExceptionMessages.forEach(errorMessage -> {
        if (StringUtils.containsAny(errorMessage, MANDATORY_FIELD_VIOLATION_OR_CONDITIONAL_VIOLATION, DEPENDENCY_VIOLATION)) {
            mandatoryListSet.add(StringUtils.substring(errorMessage, errorMessage.indexOf('[') + 1, errorMessage.indexOf(']')));
        }
    });
    return new ArrayList<>(mandatoryListSet);
}

private static List<String> parseInvalids(List<String> validationExceptionMessages) {
    Set<String> invalidParamsSet = new HashSet<>();
    validationExceptionMessages.forEach(errorMessage -> {
        if (StringUtils.containsAny(errorMessage, MIN_LENGTH_VIOLATION, MAX_LENGTH_VIOLATION, PATTERN_VIOLATION,
                FORMAT_VIOLATION_OR_ENUM_VALIDATION_VIOLATION, DATA_TYPE_VIOLATION, NUMBER_IS_LESS_THAN_VIOLATION,
                MULTIPLE_OF_VIOLATION, EXCLUSIVE_NUMBER_IS_GREATER_THAN_VIOLATION, NUMBER_IS_GREATER_THAN_VIOLATION
                , EXCLUSIVE_NUMBER_IS_LESS_THAN_VIOLATION)) {
            invalidParamsSet.add(StringUtils.substring(errorMessage, errorMessage.indexOf('/') + 1, errorMessage.indexOf(':')));
        }
    });
    return new ArrayList<>(invalidParamsSet);
}

希望能有所帮助

相关文章