leadpony / justify

Justify is a JSON validator based on JSON Schema Specification and Jakarta JSON Processing API (JSON-P).
Apache License 2.0
96 stars 18 forks source link

How to validate json document in the most strict way? #46

Closed simonmikkelsen closed 4 years ago

simonmikkelsen commented 4 years ago

I am trying to validate a json document against a json schema and want the validation to be as strict as possible. For that reason I try to create as strict configurations as possible:

    public void validateDocAgainstSchema(String docPath, String schemaPath) {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        JsonSchemaReaderFactory schemaReaderFactory = service.createSchemaReaderFactoryBuilder()
                .withCustomFormatAttributes(false)
                .withStrictKeywords(false)
                .withStrictFormats(false)
                .build();
        JsonSchema schema;
        try (JsonSchemaReader schemaReader = schemaReaderFactory.createSchemaReader(classloader.getResourceAsStream(schemaPath))) {
            schema = schemaReader.read();
        }
        InputStream documentStream = ClassLoader.getSystemResourceAsStream(docPath);
        Map<String, Object> validationConfig = service.createValidationConfig()
                .withDefaultValues(false)
                .withProblemHandler(ProblemHandler.throwing())
                .withSchema(schema)
                .getAsMap();

        try (JsonParser parser = service.createParserFactory(validationConfig).createParser(documentStream)) {
            while (parser.hasNext()) {
                parser.next();
                // forces parsing and validation of the document.
            }
        }
    }

This works fine in regard to required fields which are missing, but I have examples of some errors that are not cought, which I had hoped to catch:

A field is defined with "type": "number" in the json schema, but if I give it the value "14N" in the json document, no error is reported. I insert a field in the json document which is not mentioned in the json schema, but no error is reported and when parsing the json document in the last while loop all values are reported without problems.

Am I missing some configuration or simmilar to get as strict a validation as possible for a given json schema?

leadpony commented 4 years ago

@simonmikkelsen

JSON schema

{
    "type": "number"
}

JSON document

"14N"

Running Justify-CLI reports the following errors.

$ justify -s issue46.schema.json -i issue46.json
Validating the schema "issue46.schema.json"...
Justified the correctness of the schema "issue46.schema.json".
Validating the instance "issue46.json"...
[1,5][] The value must be of number type, but actual type is string.
At least 1 problem(s) were found in the instance "issue46.json".

Could you show me the exact JSON schema and JSON document you have tried?

simonmikkelsen commented 4 years ago

Thank you for your reply. After comparing my solution to the cli I changed it to the following that gives the result I hoped for:

public void validateDocAgainstSchema(String docPath, String schemaPath) {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        InputStream documentStream = ClassLoader.getSystemResourceAsStream(docPath);

        JsonSchemaReaderFactory factory = service.createSchemaReaderFactoryBuilder()
                .withCustomFormatAttributes(false)
                .withStrictKeywords(true)
                .withStrictFormats(true)
                .build();
        JsonSchema schema;
        try (JsonSchemaReader reader = factory.createSchemaReader(classloader.getResourceAsStream(schemaPath))) {
            schema = reader.read();
        }

        try (JsonReader reader = service.createReader(documentStream, schema, ProblemHandler.throwing())) {
            reader.readValue();
        }
}

Both the trys can throw exceptions that must be caught (or another ProblemHandler must be used).