everit-org / json-schema

JSON Schema validator for java, based on the org.json API
Apache License 2.0
860 stars 281 forks source link

Override default date-time validator #308

Closed luismoramedina closed 5 years ago

luismoramedina commented 5 years ago

Hi, we have noticed that in 1.4 version of the library the date-time format validation was strict (Lenient = false). So, when you validate a wrong date (for example: 2019-02-30) the library throws a validation error.

With the latest version, this date (2019-02-30) is a valid date-time for the library. We are trying to use a custom validator for date-time and perform a strict validation, but we cannot override the default date-time validation. Is it possible?

Thanks in advance.

Related: https://github.com/everit-org/json-schema/issues/22

My code: JSONObject rawSchema = new JSONObject(new JSONTokener(... draftV7 schema...)); SchemaLoader schemaLoader = SchemaLoader.builder() .schemaJson(rawSchema) .addFormatValidator("date-time", new MyDateTimeValidator()) .build(); //This code replaces my date-time format validator with the default one :-( ...

dbottini2 commented 5 years ago

Hi, I wish to override the default date-time validator as well, but my use case is a little different.

We are trying to adopt the everit library for schema validation, but are running into a hurdle where everit only validates RFC 3339 timestamps, while the library we currently use validates all ISO-8601 timestamps. While RFC 3339 is technically the correct definition to use according to the json schema specs, we can't possibly change from ISO -> RFC in every situation where timestamp is serialized/deserialized.

What we would like to be able to do is to override the date-time format validator so we can accept ISO-8601. It would look something like this, I hope.

String schemaRaw =  "{\n" +
        "  \"required\": [\n" +
        "    \"time\"\n" +
        "  ],\n" +
        "  \"properties\": {\n" +
        "    \"time\": {\n" +
        "      \"type\": \"string\",\n" +
        "      \"format\": \"date-time\"\n" +
        "    }\n" +
        "  }\n" +
        "}";
String payload = "{\n" +
        "  \"time\": \"2019-06-17T19:16:40+0000\"\n" + 
// This is an ISO-8601 conformant timestamp, but not an RFC 3339 conformant timestamp.
        "}";
JSONObject object = new JSONObject(payload);
Schema schema = SchemaLoader.builder()
        .addFormatValidator(new ISODateTimeFormatValidator())
        .schemaJson(new JSONObject(schemaRaw))
        .build()
        .load()
        .build();
schema.validate(object);
luismoramedina commented 5 years ago

I had created a fork implementing a possible solution. You can check it here:

https://github.com/luismoramedina/json-schema/commit/4b3ed44f3f4a3bffe542237aa1faef9e17342a45

I have added a keepCustomFormatValidators flag to not override the user/custom validators.

The new integration will be like that: SONObject rawSchema = new JSONObject(new JSONTokener(... draftV7 schema...)); SchemaLoader schemaLoader = SchemaLoader.builder() .schemaJson(rawSchema) .addFormatValidator("date-time", new MyDateTimeValidator()) .keepCustomFormatValidators() .build();

erosb commented 5 years ago

Hi! Thanks for the commit. Can you please raise a pull request? The change looks good mostly. Maybe it would be better to rename the flag enableOverrideOfBuiltInFormatValidators . Thanks.

luismoramedina commented 5 years ago

Sure! i'm changing the param name and adding a vanilla test.

Thanks to you!

luismoramedina commented 5 years ago

PR opened and ci checked https://github.com/everit-org/json-schema/pull/309

If you need any changes please tell me @erosb

Thanks in advance!

PD: @dbottini2 i think this change allows you to do this validation on a custom validator