2013-01-24 18 views
16

Mam problem ze znalezieniem najprostszego sposobu sprawdzenia poprawności łańcucha JSON względem danego łańcucha znaków JSON-Schema (dla odniesienia, to jest w Javie, działa w aplikacji dla systemu Android).Java/Android - sprawdzanie poprawności łańcucha znaków JSON względem schematu String

Idealnie, chciałbym po prostu przekazać ciąg JSON i ciąg znaków JSON-schema, i zwraca boolean, czy przechodzi pomyślnie sprawdzania poprawności. Poprzez poszukiwaniach, znalazłem następujące 2 obiecujące bibliotek dla osiągnięcia tego:

http://jsontools.berlios.de/

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

Jednak pierwsza wydaje się dość przestarzały ze słabym wsparciem. Zaimplementowałem bibliotekę do mojego projektu, a nawet z ich JavaDocs, nie byłem w stanie powiedzieć, jak poprawnie zbudować obiekt "Validator" do sprawdzania poprawności.

Podobna historia z drugą, która wydaje się być na czasie z dobrym kodem testu. Jednak, co chcę zrobić, co jest bardzo proste, wydaje się być nieco zniechęcające i mylące, jak konkretnie osiągnąć to, co chcę (nawet po obejrzeniu pliku ValidateServlet.java).

Ciekawy, jeśli ktoś ma jakieś inne sugestie na dobry sposób, aby osiągnąć ten cel (z tego, co się wydaje), proste zadanie, które trzeba, czy może powinienem trzymać się drugiej opcji z góry? Z góry dziękuję!

+2

Autor json-schema-walidator tutaj ... prawda zobacz w README, że istnieje link do kodu próbek? ;) – fge

+0

Cześć, i dziękuję za wspaniałą bibliotekę! Tak, rzeczywiście, widziałem próbki kodu i faktycznie wspomniałem o tym w moim poście z osadzonym linkiem (plik ValidateServlet.java). Jeszcze raz dziękuję za tę bibliotekę! Świetne rzeczy :) – svguerin3

+0

Nie mówiłem o tym przykładzie: mówiłem o 'com.github.fge.jsonschema.examples' w javadoc;) BTW, 1.6.0 jest obecnie. – fge

Odpowiedz

10

To jest zasadniczo to, do czego służy Servlet, do którego się łączysz, więc może nie być jednolinijkowe, ale wciąż jest ekspresyjne.

useV4 i useId jak określono w aplecie, służą do określenia opcji sprawdzania poprawności dla Default to draft v4 i Use id for addressing.

Można go zobaczyć na stronie: 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(); 
} 
+0

Świetne, dziękuję! Sądzę, że prawdopodobnie potrzebowałem właśnie szturchnięcia we właściwym kierunku na prawidłowy sposób korzystania z tej biblioteki. Naprawdę to doceniam! – svguerin3

+1

Należy zauważyć, że implementacja wykrywa '$ schema' i domyślnie używa wersji roboczej v3. W większości przypadków wystarczy użyć 'JsonSchemaFactory.defaultFactory()'. – fge

13

Wdzięczny dziękuję Douglas Crockforda i Francis Galiegue do pisania procesor schematu json oparte na Java! A tester on-line w http://json-schema-validator.herokuapp.com/index.jsp jest niesamowity! Bardzo podoba mi się pomocne komunikaty o błędach (znalazłem tylko jeden przykład, w którym się nie udało), chociaż linia i kolumna i/lub kontekst byłyby jeszcze lepsze (w tej chwili otrzymujesz tylko informacje o liniach i kolumnach podczas błędów formatu JSON (dzięki Jacksonowi Na koniec chciałbym podziękować Michaelowi Droettboomowi za jego samouczek świetny (nawet jeśli dotyczył on tylko Pythona, Ruby i C, jednocześnie wyraźnie ignorując najlepszy język wszystkich :-)).

Dla tych, którzy ją przegapili (tak jak na początku), są przykłady na github.com/fge/json-schema-processor-przykładach. Chociaż przykłady te są imponujące, nie są to proste przykłady walidacji jsonów, które pierwotnie były wymagane (i których również szukałem). Proste przykłady można znaleźć na stronie github.com/fge/json-schema-validator/blob/master/src/main/java/com/github/fge/jsonschema/examples/Example1.java

Powyższy kod Alexa nie działał dla mnie, ale był bardzo pomocny; mój pom wyciąga najnowsze stabilne wydanie, w wersji 2.0.1 z następującą zależnością wstawioną w moim maven pom.plik xml:

<dependency> 
    <groupId>com.github.fge</groupId> 
    <artifactId>json-schema-validator</artifactId> 
    <version>2.0.1</version> 
</dependency> 

Następnie poniższy kod Java działa dobrze dla mnie:

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); 
} 

} 

Mój wynik z powyższego kodu jest:

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!

+1

Dobry przykład Dzięki! – vatsa

+0

Świetnie! Dziękuję Ci – neverwinter

2

@ odpowiedź Alex pracował dla mnie na Androida ale wymaga mnie do Multi-dex i dodać:

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' 
    } 

do mojego build.gradle

Powiązane problemy