2013-01-24 27 views
16

Tôi gặp khó khăn khi tìm cách đơn giản nhất để xác nhận một chuỗi JSON chống lại một chuỗi JSON-schema nhất định (để tham khảo, đây là trong Java, chạy trong một ứng dụng Android).Java/Android - Validate Chuỗi JSON chống Chuỗi schema

Lý tưởng nhất, tôi muốn chuyển một chuỗi JSON và một chuỗi JSON-schema, và nó trả về một boolean về việc liệu nó có vượt qua xác thực hay không. Qua tìm kiếm, tôi đã tìm thấy 2 thư viện đầy hứa hẹn sau đây để đạt được điều này:

http://jsontools.berlios.de/

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

Tuy nhiên, một trong những đầu tiên dường như khá lỗi thời với sự hỗ trợ người nghèo. Tôi đã triển khai thư viện vào dự án của mình và thậm chí với các JavaDocs của chúng, tôi không thể biết cách xây dựng một đối tượng "Validator" đúng cách để xác thực.

câu chuyện tương tự với một trong 2, mà có vẻ là up-to-date với mã thử nghiệm tốt. Tuy nhiên, với những gì tôi muốn làm, điều này rất đơn giản, có vẻ hơi khó khăn và khó hiểu về cách thực hiện cụ thể những gì tôi muốn (ngay cả sau khi xem tập tin ValidateServlet.java).

Tò mò nếu có ai có bất kỳ đề xuất nào khác để thực hiện điều này (từ những gì có vẻ), nhiệm vụ đơn giản cần, hoặc nếu tôi có lẽ cần phải gắn bó với tùy chọn thứ 2 từ trên cao? Cảm ơn trước!

+2

Tác giả của json-schema-validator đây ... Chẳng phải bạn thấy trong README có một liên kết để mã mẫu? ;) – fge

+0

Xin chào và cảm ơn bạn vì thư viện tuyệt vời của bạn! Có thực sự, tôi đã nhìn thấy các mẫu mã và thực sự đề cập đến nó trong bài viết của tôi với một liên kết nhúng (tệp ValidateServlet.java). Một lần nữa xin cảm ơn thư viện này! Công cụ tuyệt vời :) – svguerin3

+0

Tôi đã không nói về mẫu này: Tôi đã nói về 'com.github.fge.jsonschema.examples' trong javadoc;) BTW, 1.6.0 đã hết. – fge

Trả lời

10

Đây thực chất là những gì các Servlet bạn liên quan đến thực hiện, vì vậy nó có thể không phải là một one-liner nhưng nó vẫn là biểu cảm.

useV4useId như được chỉ định trên servlet, để chỉ định tùy chọn xác thực cho Default to draft v4Use id for addressing.

Bạn có thể nhìn thấy nó trực tuyến: 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

Brilliant, cảm ơn bạn! Tôi đoán tôi có lẽ chỉ cần di chuyển đúng hướng theo đúng cách để sử dụng thư viện này. Thực sự đánh giá cao nó! – svguerin3

+1

Lưu ý rằng việc triển khai phát hiện '$ schema' và mặc định là draft v3. Trong hầu hết các trường hợp, bạn chỉ cần sử dụng 'JsonSchemaFactory.defaultFactory()'. – fge

13

Một biết ơn cảm ơn bạn Douglas Crockford và Francis Galiegue để viết bộ xử lý đồ json java dựa trên! Và thử nghiệm trực tuyến tại http://json-schema-validator.herokuapp.com/index.jsp thật tuyệt vời! Tôi thực sự thích các thông báo lỗi hữu ích (tôi chỉ tìm thấy một ví dụ trong đó chúng không thành công), mặc dù dòng và cột và/hoặc ngữ cảnh thậm chí còn tốt hơn (ngay bây giờ, bạn chỉ nhận được thông tin dòng và cột trong các lỗi định dạng JSON (lịch sự của Jackson)). Cuối cùng, tôi muốn gửi lời cảm ơn Michael Droettboom cho lớn hướng dẫn của mình (thậm chí nếu anh ta chỉ che Python, Ruby, và C trong khi dễ thấy lờ đi ngôn ngữ tốt nhất của tất cả :-)).

Đối với những người bị mất nó (như tôi đã làm lúc đầu), có những ví dụ là tại github.com/fge/json-schema-processor-examples. Trong khi các ví dụ này rất ấn tượng, chúng không phải là các ví dụ xác thực json đơn giản được yêu cầu ban đầu (và tôi cũng đang tìm kiếm). Các ví dụ đơn giản là tại github.com/fge/json-schema-validator/blob/master/src/main/java/com/github/fge/jsonschema/examples/Example1.java

Mã của Alex ở trên không hoạt động cho tôi, nhưng rất hữu ích; pom của tôi là kéo bản phát hành ổn định mới nhất, phiên bản 2.0.1 với sự phụ thuộc sau được chèn vào trong maven của tôi.xml file:

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

Sau đó, mã java sau hoạt động tốt đối với tôi:

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

} 

kết quả của tôi từ các mã trên là:

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 

Thưởng thức!

+1

Ví dụ tuyệt vời Cảm ơn! – vatsa

+0

Tuyệt vời! Cảm ơn bạn – neverwinter

2

@ câu trả lời của Alex làm việc cho tôi trên Android nhưng đòi hỏi tôi phải Multi-dex và thêm:

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

để tôi build.gradle

Các vấn đề liên quan