Library for Json Schema and Validation in Java

9.9k views Asked by At

I can see there are some libraries that generate Json Schema and other which can validate. Could you please suggest some library (with examples and active one) that can provide both functionality in Java. I am looking for Apache licensed library.

I have tried Jackson and Gson.
Gson does not support neither json schema creation and validation.
Jackson support json schema generation but not fully (e.g. it does not support default value in json schema)

Regards,

2

There are 2 answers

12
Carsten On BEST ANSWER

The main scope of GSON and Jackson is to handle the serialization/deserialization of your data to/from JSON. Both the generation and validation of JSON Schemas are not their (main) concern.

As per comments on your other question (How to display default value in JSON Schema using Jackson), there are a couple of alternatives out there for the schema generation – the same applies to their validation.

List of Implementations (Generation & Validation)

As per R.Groote's answer, you can find some (but not all) of them on https://json-schema.org/implementations.html – both generation and validation libraries.

Validation

Personally, I've only used networknt/json-schema-validator so far and found it very intuitive and easy to use. It uses Jackson under the hood, which was practical in my use-case as I was already using the same library for the (de)serialization of data from/to JSON – so less additional dependencies.


Generation

Disclaimer: here comes the biased part as I'm the creator of victools/jsonschema-generator.

One example for a JSON Schema generation library would be victools/jsonschema-generator. That also uses Jackson internally, so again similar dependencies to the networknt/json-schema-validator.

The jsonschema-generator library does not populate the "default" value out-of-the-box, but you could easily configure it like this (based on the Jackson @JsonProperty annotation as per your other question):

SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON);
configBuilder.forFields().withDefaultResolver(field -> {
    JsonProperty annotation = field.getAnnotationConsideringFieldAndGetter(JsonProperty.class);
    return annotation == null || annotation.defaultValue().isEmpty() ? null : annotation.defaultValue());
});
SchemaGenerator generator = new SchemaGenerator(configBuilder.build());
JsonNode jsonSchema = generator.generateSchema(YourClass.class);

System.out.println(jsonSchema.toString());

If you are catering for numeric default values, you might have to include some conditional parsing of the @JsonProperty.defaultValue String then.

Additionally, if you want some more specific handling of Jackson annotations you could also consider adding the optional victools/jsonschema-module-jackson as well then.


EDIT (as response to your concerns having to define the default values twice – in the code and on the annotation):

With the victools/jsonschema-generator you have full control over where the default value is coming from. One possible approach could be to look-up the default values from actual instances of the respective objects being encountered – here filtering by your own package to skip external types.
The following is just a rough example of what is possible:

ConcurrentMap<Class<?>, Object> instanceCache = new ConcurrentHashMap<>();
configBuilder.forFields().withDefaultResolver(field -> {
    Class<?> declaringClass = field.getDeclaringType().getErasedType();
    if (!field.isFakeContainerItemScope()
            && declaringClass.getName().startsWith("your.package")) {
        MethodScope getter = field.findGetter();
        if (getter != null) {
            try {
                Object instance = instanceCache.computeIfAbsent(declaringClass, declaringClass::newInstance);
                Object defaultValue = getter.getRawMember().invoke(instance);
                return defaultValue;
            } catch (Exception ex) {
                // most likely missing a no-args constructor
            }
        }
    }
    return null;
});
0
R.Groote On

I prefer to use GSON or Jackson: - https://www.baeldung.com/jackson-vs-gson

You could use Justify or json-schema-validator see below links: - https://json-schema.org/implementations.html - Validate JSON schema compliance with Jackson against an external schema file

I hope the above links give you enough information