2013-08-09 41 views
13

Dịch vụ nghỉ ngơi cần xác thực tất cả dữ liệu json đến dựa vào lược đồ json. Các lược đồ json có thể truy cập công khai và có thể được truy xuất thông qua các yêu cầu http.Làm cách nào để xác thực dữ liệu JSON vào bên trong một dịch vụ REST?

Tôi đang sử dụng jackson-framwork cho marshaling và unmarshaling giữa java và json. Cho đến nay tôi không thể tìm thấy bất kỳ khả năng để xác nhận dữ liệu chống lại lược đồ bằng cách sử dụng jackson.

Tôi cũng đã thử khuôn khổ JsonTools rõ ràng là có chức năng xác thực như vậy. Nhưng thật không may là tôi không thể có được xác nhận để làm việc. Why JsonTool schema validation isn't working?

Tôi làm cách nào để xác thực?

+0

Duplicate của http://stackoverflow.com/questions/2499126/json-schema-validation-using-java? – condit

+0

Cuối cùng tôi đã tìm ra cách thực hiện xác nhận hợp lệ json cho các dịch vụ REST. Tôi sẽ đăng ví dụ hoàn chỉnh làm câu trả lời ngay khi câu hỏi này không còn là 'giữ lại ' –

+0

Xin chào. FYI, phiếu giảm giá sẽ là do stackoverflow không được coi là diễn đàn tốt nhất cho các câu hỏi dựa trên ý kiến, chẳng hạn như thư viện tốt nhất để làm X. Xem [help section] (http://stackoverflow.com/help/dont là gì -ask) – theon

Trả lời

12

Tôi đã tìm kiếm phương pháp hay nhất để thực thi xác thực cho dữ liệu json đến vào dịch vụ RESTful. Đề xuất của tôi là sử dụng một số MessageBodyReader thực hiện xác thực bên trong phương thức readFrom. Dưới đây là một ví dụ đọc tin nhắn-cơ thể mà không phải là chung chung vì lợi ích của sự đơn giản.

Tôi cũng đã được can thiệp vào việc tìm ra khung làm việc tốt nhất để thực hiện xác thực dữ liệu json. Bởi vì tôi sử dụng khung công tác jackson (phiên bản 1.8.5) cho việc sắp xếp và sửa đổi giữa json và java, nên sẽ tốt hơn nếu khung công tác này cung cấp chức năng xác nhận dữ liệu json. Thật không may tôi không thể tìm thấy bất kỳ khả năng để làm điều này với jackson. Cuối cùng, tôi đã làm việc này với JSON-schema-validator có sẵn tại https://github.com. Phiên bản tôi sử dụng là 2.1.7

import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Type; 

import javax.servlet.ServletContext; 
import javax.ws.rs.Consumes; 
import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.MultivaluedMap; 
import javax.ws.rs.ext.MessageBodyReader; 
import javax.ws.rs.ext.Provider; 

import org.codehaus.jackson.map.ObjectMapper; 

import at.fhj.ase.dao.data.Address; 
import at.fhj.ase.xmlvalidation.msbreader.MessageBodyReaderValidationException; 

import com.fasterxml.jackson.databind.JsonNode; 
import com.github.fge.jackson.JsonLoader; 
import com.github.fge.jsonschema.exceptions.ProcessingException; 
import com.github.fge.jsonschema.main.JsonSchemaFactory; 
import com.github.fge.jsonschema.main.JsonValidator; 
import com.github.fge.jsonschema.report.ProcessingReport; 

@Provider 
@Consumes(MediaType.APPLICATION_JSON) 
public class AddressJsonValidationReader implements MessageBodyReader<Address> { 

    private final String jsonSchemaFileAsString; 

    public AddressJsonValidationReader(@Context ServletContext servletContext) { 
     this.jsonSchemaFileAsString = servletContext 
       .getRealPath("/json/Address.json"); 
    } 

    @Override 
    public boolean isReadable(Class<?> type, Type genericType, 
      Annotation[] annotations, MediaType mediaType) { 
     if (type == Address.class) { 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public Address readFrom(Class<Address> type, Type genericType, 
      Annotation[] annotations, MediaType mediaType, 
      MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
      throws IOException, WebApplicationException { 

     final String jsonData = getStringFromInputStream(entityStream); 
     System.out.println(jsonData); 

     InputStream isSchema = new FileInputStream(jsonSchemaFileAsString); 
     String jsonSchema = getStringFromInputStream(isSchema); 

     /* 
     * Perform JSON data validation against schema 
     */ 
     validateJsonData(jsonSchema, jsonData); 

     /* 
     * Convert stream to data entity 
     */ 
     ObjectMapper m = new ObjectMapper(); 
     Address addr = m.readValue(stringToStream(jsonData), Address.class); 

     return addr; 
    } 

    /** 
    * Validate the given JSON data against the given JSON schema 
    * 
    * @param jsonSchema 
    *   as String 
    * @param jsonData 
    *   as String 
    * @throws MessageBodyReaderValidationException 
    *    in case of an error during validation process 
    */ 
    private void validateJsonData(final String jsonSchema, final String jsonData) 
      throws MessageBodyReaderValidationException { 
     try { 
      final JsonNode d = JsonLoader.fromString(jsonData); 
      final JsonNode s = JsonLoader.fromString(jsonSchema); 

      final JsonSchemaFactory factory = JsonSchemaFactory.byDefault(); 
      JsonValidator v = factory.getValidator(); 

      ProcessingReport report = v.validate(s, d); 
      System.out.println(report); 
      if (!report.toString().contains("success")) { 
       throw new MessageBodyReaderValidationException(
         report.toString()); 
      } 

     } catch (IOException e) { 
      throw new MessageBodyReaderValidationException(
        "Failed to validate json data", e); 
     } catch (ProcessingException e) { 
      throw new MessageBodyReaderValidationException(
        "Failed to validate json data", e); 
     } 
    } 

    /** 
    * Taken from <a href= 
    * "http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/" 
    * >www.mkyong.com</a> 
    * 
    * @param is 
    *   {@link InputStream} 
    * @return Stream content as String 
    */ 
    private String getStringFromInputStream(InputStream is) { 
     BufferedReader br = null; 
     StringBuilder sb = new StringBuilder(); 

     String line; 
     try { 

      br = new BufferedReader(new InputStreamReader(is)); 
      while ((line = br.readLine()) != null) { 
       sb.append(line); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (br != null) { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     return sb.toString(); 
    } 

    private InputStream stringToStream(final String str) throws UnsupportedEncodingException { 
     return new ByteArrayInputStream(str.getBytes("UTF-8")); 
    } 

} 
6
import com.github.fge.jsonschema.core.report.ProcessingReport; 
import com.github.fge.jsonschema.main.JsonSchema; 
import com.github.fge.jsonschema.main.JsonSchemaFactory; 
import com.github.fge.jackson.JsonLoader; 
import com.fasterxml.jackson.databind.JsonNode; 
public class ValidationJSON { 
    public static void main(Stirng[] arr){ 
     String jsonData="{\"name\": \"prem\"}"; 
     String jsonSchema=""; //Schema we can genearte online using http://jsonschema.net/ 
     final JsonNode data = JsonLoader.fromString(jsonData); 
     final JsonNode schema = JsonLoader.fromString(jsonSchema); 

     final JsonSchemaFactory factory = JsonSchemaFactory.byDefault(); 
     JsonValidator validator = factory.getValidator(); 

     ProcessingReport report = validator.validate(schema, data); 
     System.out.println(report.isSuccess()); 
    } 

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