Java/Android - проверка строки JSON по строковой схеме
У меня возникли проблемы с поиском самого простого способа проверки строки JSON для данной строки JSON-схемы (для справки, это в Java, работающей в приложении для Android).
В идеале, я бы хотел просто передать строку JSON String и строку JSON-схемы, и он возвращает логическое значение относительно того, проходит ли он проверку. Через поиск я нашел следующие 2 многообещающие библиотеки для этого:
http://jsontools.berlios.de/
https://github.com/fge/json-schema-validator
Однако первый из них выглядит довольно устаревшим с плохой поддержкой. Я реализовал библиотеку в своем проекте и даже с помощью своих JavaDocs, я не смог сказать, как правильно построить объект "Validator" для проверки.
Аналогичная история со вторым, которая, кажется, актуальна с хорошим тестовым кодом. Однако для того, что я хочу сделать, что очень просто, кажется немного сложным и запутанным в том, как конкретно выполнить то, что я хочу (даже после просмотра ValidateServlet.java).
Любопытно, есть ли у кого-нибудь другие предложения по хорошему способу выполнить это (от того, что кажется), простая задача, которая нужна, или если мне, возможно, придется придерживаться второго варианта сверху? Спасибо заранее!
Ответы
Ответ 1
Это, по сути, то, с чем вы связались с сервлетами, поэтому он не может быть однострочным, но он все же является выразительным.
useV4
и useId
, как указано на сервлете, предназначены для указания опции проверки для Default to draft v4
и Use id for addressing
.
Вы можете увидеть его онлайн: 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();
}
Ответ 2
Благодарю вас за Дугласа Крокфорда и Фрэнсиса Галиге за то, что он написал java-схему java-схемы! И он-лайн тестер на http://json-schema-validator.herokuapp.com/index.jsp является потрясающим! Мне очень нравятся полезные сообщения об ошибках (я нашел только один пример, в котором они не выполнялись), хотя строка и столбец и/или контекст будут еще лучше (прямо сейчас вы получаете информацию о строках и столбцах во время ошибок формата JSON (любезно предоставлено Jackson ) Наконец, я хотел бы поблагодарить Майкла Дроттбума за его большой учебник (даже если он только покрыл Python, Ruby и C, в то же время игнорируя лучший язык всех: -)).
Для тех, кто пропустил это (как и раньше), есть примеры в github.com/fge/json-schema-processor-examples. Хотя эти примеры очень впечатляют, они не являются простыми примерами проверки json, которые первоначально запрашивались (и которые я тоже искал). Простые примеры приведены на странице github.com/fge/json-schema-validator/blob/master/src/main/java/com/github/fge/jsonschema/examples/Example1.java
Код Alex выше не работал у меня, но был очень полезным; мой pom вытаскивает последний стабильный релиз версии 2.0.1 со следующей зависимостью, вставленной в мой файл maven pom.xml:
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.0.1</version>
</dependency>
Тогда следующий код java отлично работает для меня:
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);
}
}
Мой результат из приведенного выше кода:
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
Наслаждайтесь!
Ответ 3
Ответ на @Alex работал у меня на Android, но мне потребовалось Multi-dex и добавить:
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'
}
на мой build.gradle