【问题标题】:Java/Android - Validate String JSON against String schemaJava/Android - 根据字符串模式验证字符串 JSON
【发布时间】:2013-01-24 21:51:47
【问题描述】:

我很难找到针对给定 JSON 模式字符串验证 JSON 字符串的最简单方法(作为参考,这是在 Java 中,在 Android 应用程序中运行)。

理想情况下,我只想传入一个 JSON 字符串和一个 JSON 模式字符串,它会返回一个布尔值,说明它是否通过了验证。通过搜索,我发现了以下 2 个有希望的库来实现这一点:

http://jsontools.berlios.de/

https://github.com/fge/json-schema-validator

但是,第一个似乎已经过时,支持不佳。我在我的项目中实现了该库,即使使用他们的 JavaDocs,我也无法判断如何正确构建“验证器”对象以进行验证。

与第二个类似的故事,似乎是最新的,具有良好的测试代码。但是,对于我想做的事情,这很简单,对于如何具体完成我想要的事情似乎有点令人生畏和困惑(即使在查看了ValidateServlet.java 文件之后)。

想知道是否有人对完成此任务的好方法有任何其他建议(从看起来),需要的简单任务,或者我是否需要坚持上面的第二个选项?提前致谢!

【问题讨论】:

  • 这里是 json-schema-validator 的作者...您没有在自述文件中看到代码示例的链接吗? ;)
  • 您好,感谢您的出色图书馆!是的,确实,我确实看到了代码示例,并且在我的帖子中实际上提到了它并带有一个嵌入式链接(ValidateServlet.java 文件)。再次感谢这个图书馆!好东西:)
  • 我说的不是这个示例:我说的是 javadoc 中的com.github.fge.jsonschema.examples ;) 顺便说一句,1.6.0 已经发布。
  • 啊,我当时没注意到!感谢您对此以及新版本的提醒。 :)
  • @fge 我似乎无法在 Android 目标 api 23 上运行此功能

标签: java android json jsonschema


【解决方案1】:

非常感谢 Douglas Crockford 和 Francis Galiegue 编写了基于 java 的 json 模式处理器! http://json-schema-validator.herokuapp.com/index.jsp 的在线测试员很棒!我真的很喜欢有用的错误消息(我只发现了一个失败的示例),尽管行和列和/或上下文会更好(现在,您只能在 JSON 格式错误期间获得行和列信息(由 Jackson 提供) ). 最后,我要感谢 Michael Droettboom 的伟大教程(即使他只涵盖了 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

享受吧!

【讨论】:

  • 很好的例子,谢谢!
【解决方案2】:

这本质上就是您链接到的 Servlet 所做的事情,因此它可能不是单行的,但它仍然具有表现力。

servlet 上指定的useV4useId 用于指定Default to draft v4Use 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();
}

【讨论】:

  • 太棒了,谢谢!我想我可能只是需要在正确的方向上推动使用这个库的正确方式。真的很感激!
  • 请注意,该实现检测到$schema 并默认为draft v3。在大多数情况下,您只需使用JsonSchemaFactory.defaultFactory()
【解决方案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

【讨论】:

  • 谢谢!注意:pickFirst 在这里很重要。不要使用exclude:虽然它使编译通过,但它会导致其他问题,因为代码依赖于模式文件的存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 1970-01-01
  • 2018-07-06
相关资源
最近更新 更多