在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:everit-org/json-schema开源软件地址:https://github.com/everit-org/json-schema开源编程语言:Java 100.0%开源软件介绍:JSON Schema Validator
This project is an implementation of the JSON Schema Draft v4, Draft v6 and Draft v7 specifications. It uses the org.json API (created by Douglas Crockford) for representing JSON data. When to use this library?Lets assume that you already know what JSON Schema is, and you want to utilize it in a Java application to validate JSON data. But - as you may have already discovered - there is also an other Java implementation of the JSON Schema specification. So here are some advices about which one to use:
Maven installationAdd the following dependency to your <dependency>
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema</artifactId>
<version>1.14.1</version>
</dependency> Note about older versions: versions between Java6/7 versionsThere were a couple of attempts to make the library work on Java 6/7. A java6 port of version 1.9.2 was developed by @mindbender1 and it is accessible through Maven Central with the following coordinates: <dependency>
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema-jdk6</artifactId>
<version>1.9.2</version>
</dependency> Backports of older versions:
Quickstartimport org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
// ...
try (InputStream inputStream = getClass().getResourceAsStream("/path/to/your/schema.json")) {
JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
Schema schema = SchemaLoader.load(rawSchema);
schema.validate(new JSONObject("{\"hello\" : \"world\"}")); // throws a ValidationException if this object is invalid
} Draft 4, Draft 6 or Draft 7?JSON Schema has currently 4 major releases, Draft 3, Draft 4, Draft 6 and Draft 7. This library implements the 3 newer ones, you can have a quick look at the differences here and here. Since the two versions have a number of differences - and draft 6 is not backwards-compatible with draft 4 - it is good to know which version will you use. The best way to denote the JSON Schema version you want to use is to include its meta-schema URL in the document root with the Quick reference:
If you want to specify the meta-schema version explicitly then you can change the default from Draft 4 to Draft 6 / 7 by configuring the loader this way: SchemaLoader loader = SchemaLoader.builder()
.schemaJson(yourSchemaJSON)
.draftV6Support() // or draftV7Support()
.build();
Schema schema = loader.load().build(); Investigating failuresStarting from version To demonstrate the above concepts, lets see an example. Lets consider the following schema: {
"type" : "object",
"properties" : {
"rectangle" : {"$ref" : "#/definitions/Rectangle" }
},
"definitions" : {
"size" : {
"type" : "number",
"minimum" : 0
},
"Rectangle" : {
"type" : "object",
"properties" : {
"a" : {"$ref" : "#/definitions/size"},
"b" : {"$ref" : "#/definitions/size"}
}
}
}
} The following JSON document has only one violation against the schema (since "a" cannot be negative): {
"rectangle" : {
"a" : -5,
"b" : 5
}
} In this case the thrown try {
schema.validate(rectangleSingleFailure);
} catch (ValidationException e) {
// prints #/rectangle/a: -5.0 is not higher or equal to 0
System.out.println(e.getMessage());
} Now - to illustrate the way that multiple violations are handled - let's consider the following JSON document, where both the "a" and "b" properties violate the above schema: {
"rectangle" : {
"a" : -5,
"b" : "asd"
}
} In this case the thrown try {
schema.validate(rectangleMultipleFailures);
} catch (ValidationException e) {
System.out.println(e.getMessage());
e.getCausingExceptions().stream()
.map(ValidationException::getMessage)
.forEach(System.out::println);
} This will print the following output:
JSON report of the failuresSince version
Please take into account that the complete failure report is a hierarchical tree structure: sub-causes of a cause can
be obtained using ValidationListeners - Tracking the validation process
Example: import org.everit.json.schema.Validator;
...
Validator validator = Validator.builder()
.withListener(new YourValidationListenerImplementation())
.build();
validator.performValidation(schema, input); The currently supported events:
See the javadoc of the Early failure modeBy default the validation error reporting in collecting mode (see the "Investigating failures" chapter). That is convenient for having a detailed error report, but under some circumstances it is more appropriate to stop the validation when a failure is found without checking the rest of the JSON document. To toggle this fast-failing validation mode
Example: import org.everit.json.schema.Validator;
...
Validator validator = Validator.builder()
.failEarly()
.build();
validator.performValidation(schema, input); Note: the Lenient modeIn some cases, when validating numbers or booleans, it makes sense to accept string values that are parseable as such primitives, because any successive processing will also automatically parse these literals into proper numeric and logical values. Also, non-string primitive values are trivial to convert to strings, so why not to permit any json primitives as strings? For example, let's take this schema: {
"properties": {
"booleanProp": {
"type": "boolean"
},
"integerProp": {
"type": "integer"
},
"nullProp": {
"type": "null"
},
"numberProp": {
"type": "number"
},
"stringProp": {
"type": "string"
}
}
} The following JSON document fails to validate, although all of the strings could easily be converted into appropriate values: {
"numberProp": "12.34",
"integerProp": "12",
"booleanProp": "true",
"nullProp": "null",
"stringProp": 12.34
} In this case, if you want the above instance to pass the validation against the schema, you need to use the lenient primitive validation configuration turned on. Example: import org.everit.json.schema.*;
...
Validator validator = Validator.builder()
.primitiveValidationStrategry(PrimitiveValidationStrategy.LENIENT)
.build();
validator.performValidation(schema, input); Note: in lenient parsing mode, all 22 possible boolean literals will be accepted as logical values. Default valuesThe JSON Schema specification defines the "default" keyword for denoting default values, though it doesn't explicitly state how it should
affect the validation process. By default this library doesn't set the default values, but if you need this feature, you can turn it on
by the {
"properties": {
"prop": {
"type": "number",
"default": 1
}
}
} JSONObject input = new JSONObject("{}");
System.out.println(input.get("prop")); // prints null
Schema schema = SchemaLoader.builder()
.useDefaults(true)
.schemaJson(rawSchema)
.build()
.load().build();
schema.validate(input);
System.out.println(input.get("prop")); // prints 1 If there are some properties missing from RegExp ImplementationsFor supporting the
While the RE2J library provides significantly better performance than The RE2J implementation can be activated with the SchemaLoader loader = SchemaLoader.builder()
.regexpFactory(new RE2JRegexpFactory())
// ...
.build(); Notes:
readOnly and writeOnly contextThe library supports the schema.json: {
"properties": {
"id": {
"type": "number",
"readOnly": true
}
}
} Validation code snippet: Validator validator = Validator.builder()
.readWriteContext(ReadWriteContext.WRITE)
.build();
validator.performValidation(schema, new JSONObject("{\"id\":42}")); In this case we told the validator that the validation happens in Format validatorsStarting from version The supported formats vary depending on the schema spec version you use (since the standard formats were introduced in different versions on the validation specification). Here is a compatibility table of the supported standard formats:
The library also supports adding custom format validators. To use a custom validator basically you have to
ExampleLets assume the task is to create a custom validator which accepts strings with an even number of characters. The custom public class EvenCharNumValidator implements FormatValidator {
@Override
public Optional<String> validate(final String subject) {
if (subject.length() % 2 == 0) {
return Optional.empty();
} else {
return Optional.of(String.format("the length of string [%s] is odd", subject));
}
}
} To bind the JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
SchemaLoader schemaLoader = SchemaLoader.builder()
.schemaJson(rawSchema) // rawSchema is the JSON representation of the schema utilizing the "evenlength" non-standard format
.addFormatValidator("evenlength", new EvenCharNumValidator()) // the EvenCharNumValidator gets bound to the "evenlength" keyword
.build();
Schema schema = schemaLoader.load().build(); // the schema is created using the above created configuration
schema.validate(jsonDocument); // the document validation happens here $ref resolutionIn a JSON Schema document it is possible to use relative URIs to refer previously defined
types. Such references are expressed using the In the case of this implementation it is possible to explicitly define an absolute URI serving as the base URI (resolution scope) using the appropriate builder method: SchemaLoader schemaLoader = SchemaLoader.builder()
.schemaJson(jsonSchema)
.resolutionScope("http://example.org/") // setting the default resolution scope
.build(); Loading from the classpathAs your schemas grow you will want to split that up into multiple source files and wire them with
SchemaLoader schemaLoader = SchemaLoader.builder()
.schemaClient(SchemaClient.classPathAwareClient())
.schemaJson(jsonSchema)
.resolutionScope("classpath://my/schemas/directory/") // setting the default resolution scope
.build(); Given this configuration, the following references will be properly resolved in {
"properties": {
"sameDir": { "$ref": "sameDirSchema.json" },
"absPath": { "$ref": "classpath://somewhere/else/otherschema.json" },
"httpPath": { "$ref": "http://example.org/http-works-as-usual" },
}
} and Registering schemas by URISometimes it is useful to work with preloaded schemas, to which we assign an arbitary URI (maybe an uuid) instead of
loading the schema through a URL. This can be done by assigning the schemas to a URI with the SchemaLoader schemaLoader = SchemaLoader.builder()
.registerSchemaByURI(new URI("urn:uuid:a773c7a2-1a13-4f6a-a70d-694befe0ce63"), aJSONObject)
.registerSchemaByURI(new URI("http://example.org"), otherJSONObject)
.schemaJson(j |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论