2013-08-09 19 views
13

休憩サービスは、着信jsonデータをjsonスキーマに対して検証する必要があります。 jsonスキーマは公開アクセス可能であり、HTTP要求を介して取得できます。着信JSONデータをRESTサービス内で検証するにはどうすればよいですか?

私は、javaとjsonのマーシャリングとアンマーシャリングにjackson-framworkを使用しています。これまでのところ、私はjacksonを使用してスキーマに対してデータを検証する可能性を見つけることができませんでした。

私はまた、明らかにそのような検証機能を提供するJsonToolsフレームワークを試しました。しかし、残念ながら、私には検証が機能するようにすることはできませんでした。 Why JsonTool schema validation isn't working?

どうすればこのような検証を行うことができますか?

+0

http://stackoverflow.com/questions/2499126/json-schema-validation-using-javaの重複のですか? – condit

+0

最後に、RESTサービスのjson検証を実行する方法を理解しました。私はこの質問がもはや「保留」ではなくなったので、完全な例を答えとして投稿します。 –

+0

こんにちは。参考までに、stackoverflowは、Xを実行するのに最適なライブラリなど、意見に基づく質問のための最良のフォーラムとはみなされないため、下の票があります。[ヘルプセクション](http://stackoverflow.com/help/dont -ask) – theon

答えて

12

着信jsonデータの検証をRESTfulサービスに強制するベストプラクティスを検索しました。私の提案は、readFromメソッド内の検証を実行するMessageBodyReaderを使用することです。単純化のためにジェネリックではないメッセージ本文読者の例があります。

また、jsonデータの検証に最適なフレームワークを見つけることにも力を入れました。 jsonとjavaのマーシャリングとアンマーシャリングのために私はjacksonフレームワーク(バージョン1.8.5)を使用しているので、このフレームワークがjsonデータ検証機能を提供するといいでしょう。残念ながら、私はjacksonでこれを行う可能性を見つけることができませんでした。最後に、json-schema-validatorhttps://github.com)で作業しました。私が使用したバージョンは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()); 
    } 

} 
関連する問題