web-dev-qa-db-ja.com

Java / Android-文字列スキーマに対して文字列JSONを検証する

与えられたJSONスキーマ文字列に対してJSON文字列を検証する最も簡単な方法を見つけるのに苦労しています(参考として、これはJavaで、Androidアプリ)で実行しています)。

理想的には、JSON文字列とJSONスキーマ文字列を渡すだけで、検証に合格するかどうかについてブール値を返します。検索の結果、これを実現するために次の2つの有望なライブラリが見つかりました。

http://jsontools.berlios.de/

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

ただし、最初のものはサポートが不十分でかなり古くなっているようです。ライブラリをプロジェクトに実装しましたが、JavaDocsを使用しても、検証用の「Validator」オブジェクトを適切に構築する方法がわかりませんでした。

良いテストコードで最新のように見える2番目のものと同様の話。しかし、私がやりたいことは非常に単純ですが、( ValidateServlet.Java ファイルを確認した後でも)具体的にやりたいことを実現する方法については、少し気が遠くて混乱しているようです。

これを達成するための良い方法(見たところから)、必要な簡単なタスク、または上から2番目のオプションを使用する必要があるかどうかについて他の提案があるかどうか知りたいですか?前もって感謝します!

16
svguerin3

これは基本的に、リンク先のサーブレットが行うことなので、ワンライナーではないかもしれませんが、それでも表現力があります。

サーブレットで指定されている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();
}
10
Alex

Javaベースのjsonスキーマプロセッサを作成してくれたDouglas CrockfordとFrancis Galiegueに感謝します。 http://json-schema-validator.herokuapp.com/index.jsp のオンラインテスターは素晴らしいです!行と列またはコンテキスト、あるいはその両方がさらに優れていますが、役立つエラーメッセージが本当に好きです(私はそれらが失敗した例を1つだけ見つけました)(現在、JSON形式のエラー中に行と列の情報しか取得しません(Jacksonの好意による)最後に、greatチュートリアルの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にあります

上記のアレックスのコードは私にとってはうまくいきませんでしたが、とても役に立ちました。私のpomは、次の依存関係が私のmaven pom.xmlファイルに挿入された最新の安定版リリース2.0.1を取得しています。

<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

楽しい!

13
Tihamer

@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

2
HaydenKai