如何为 JSONSchema 自定义错误消息?

How to customize error messages for JSONSchema?

有没有办法根据给定条件提供自定义错误消息? 我正在使用 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”且配置已通过,则会发生错误。我想自定义该错误,以便响应与现在相同,但带有自定义消息,如“提供者 2 无法配置。”

当前错误message/response:

{
    "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. 现在,一旦您拥有所有密钥,就可以轻松处理错误并发送自定义 error/response。

以下是我针对不同案例收集的key,希望对你有帮助-

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);
}

希望对您有所帮助