I am having trouble finding the most simple way to validate a JSON String against a given JSON-schema String (for reference, this is in Java, running in an Android app).
A grateful thank you to Douglas Crockford and Francis Galiegue for writing the java-based json schema processor! And the on-line tester at http://json-schema-validator.herokuapp.com/index.jsp is awesome! I really like the helpful error messages (I only found one example in which they failed), though line and column and/or context would be even better (right now, you only get line and column information during JSON format errors (courtesy of Jackson). Finally, I'd like to thank Michael Droettboom for his great tutorial (even if he only covered Python, Ruby, and C while conspicuously ignoring the best language of all :-)).
For those who missed it (like I did at first), there are examples are at github.com/fge/json-schema-processor-examples. While these examples are very impressive, they are not the simple json validation examples that were originally requested (and that I too was looking for). The simple examples are at github.com/fge/json-schema-validator/blob/master/src/main/java/com/github/fge/jsonschema/examples/Example1.java
Alex's code above did not work for me, but was very helpful; my pom is pulling the latest stable release, version 2.0.1 with the following dependency inserted in my maven pom.xml file:
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.0.1</version>
</dependency>
Then the following java code works fine for me:
import java.io.IOException;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jsonschema.exceptions.ProcessingException;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import com.github.fge.jsonschema.report.ProcessingMessage;
import com.github.fge.jsonschema.report.ProcessingReport;
import com.github.fge.jsonschema.util.JsonLoader;
public class JsonValidationExample
{
public boolean validate(String jsonData, String jsonSchema) {
ProcessingReport report = null;
boolean result = false;
try {
System.out.println("Applying schema: @<@<"+jsonSchema+">@>@ to data: #<#<"+jsonData+">#>#");
JsonNode schemaNode = JsonLoader.fromString(jsonSchema);
JsonNode data = JsonLoader.fromString(jsonData);
JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
JsonSchema schema = factory.getJsonSchema(schemaNode);
report = schema.validate(data);
} catch (JsonParseException jpex) {
System.out.println("Error. Something went wrong trying to parse json data: #<#<"+jsonData+
">#># or json schema: @<@<"+jsonSchema+">@>@. Are the double quotes included? "+jpex.getMessage());
//jpex.printStackTrace();
} catch (ProcessingException pex) {
System.out.println("Error. Something went wrong trying to process json data: #<#<"+jsonData+
">#># with json schema: @<@<"+jsonSchema+">@>@ "+pex.getMessage());
//pex.printStackTrace();
} catch (IOException e) {
System.out.println("Error. Something went wrong trying to read json data: #<#<"+jsonData+
">#># or json schema: @<@<"+jsonSchema+">@>@");
//e.printStackTrace();
}
if (report != null) {
Iterator<ProcessingMessage> iter = report.iterator();
while (iter.hasNext()) {
ProcessingMessage pm = iter.next();
System.out.println("Processing Message: "+pm.getMessage());
}
result = report.isSuccess();
}
System.out.println(" Result=" +result);
return result;
}
public static void main(String[] args)
{
System.out.println( "Starting Json Validation." );
JsonValidationExample app = new JsonValidationExample();
String jsonData = "\"Redemption\"";
String jsonSchema = "{ \"type\": \"string\", \"minLength\": 2, \"maxLength\": 11}";
app.validate(jsonData, jsonSchema);
jsonData = "Agony"; // Quotes not included
app.validate(jsonData, jsonSchema);
jsonData = "42";
app.validate(jsonData, jsonSchema);
jsonData = "\"A\"";
app.validate(jsonData, jsonSchema);
jsonData = "\"The pity of Bilbo may rule the fate of many.\"";
app.validate(jsonData, jsonSchema);
}
}
My result from the above code is:
Starting Json Validation.
Applying schema: @<@<{ "type": "string", "minLength": 2, "maxLength": 11}>@>@ to data: #<#<"Redemption">#>#
Result=true
Applying schema: @<@<{ "type": "string", "minLength": 2, "maxLength": 11}>@>@ to data: #<#<Agony>#>#
Error. Something went wrong trying to parse json data: #<#<Agony>#># or json schema: @<@<{ "type": "string", "minLength": 2, "maxLength": 11}>@>@. Are the double quotes included?
Result=false
Applying schema: @<@<{ "type": "string", "minLength": 2, "maxLength": 11}>@>@ to data: #<#<42>#>#
Processing Message: instance type does not match any allowed primitive type
Result=false
Applying schema: @<@<{ "type": "string", "minLength": 2, "maxLength": 11}>@>@ to data: #<#<"A">#>#
Processing Message: string is too short
Result=false
Applying schema: @<@<{ "type": "string", "minLength": 2, "maxLength": 11}>@>@ to data: #<#<"The pity of Bilbo may rule the fate of many.">#>#
Processing Message: string is too long
Result=false
Enjoy!
@Alex's answer worked for me on Android but required me to Multi-dex and add:
packagingOptions {
pickFirst 'META-INF/ASL-2.0.txt'
pickFirst 'draftv4/schema'
pickFirst 'draftv3/schema'
pickFirst 'META-INF/LICENSE'
pickFirst 'META-INF/LGPL-3.0.txt'
}
to my build.gradle
This is essentially what the Servlet you linked to does, so it may not be a one-liner but it still is expressive.
useV4
and useId
as specified on the servlet, are for specifying validations option for Default to draft v4
and Use id for addressing
.
You can see it online: http://json-schema-validator.herokuapp.com/
public boolean validate(String jsonData, String jsonSchema, boolean useV4, boolean useId) throws Exception {
// create the Json nodes for schema and data
JsonNode schemaNode = JsonLoader.fromString(jsonSchema); // throws JsonProcessingException if error
JsonNode data = JsonLoader.fromString(jsonData); // same here
JsonSchemaFactory factory = JsonSchemaFactories.withOptions(useV4, useId);
// load the schema and validate
JsonSchema schema = factory.fromSchema(schemaNode);
ValidationReport report = schema.validate(data);
return report.isSuccess();
}