如何在REST服务中validation传入的JSON数据?

rest服务需要根据json模式validation所有传入的json数据。 json模式是公共可访问的,可以通过http请求检索。

我正在使用jackson -framwork来编组java和json之间的编组和解组。 到目前为止,我找不到任何使用jacksonvalidation数据的方法。

我还尝试了JsonTools框架,它显然提出了这样的validationfunction。 但不幸的是,我无法让validation工作。 为什么JsonTool架构validation不起作用?

我该怎么做这样的validation?

我搜索了对传入的json数据进行RESTful服务validation的最佳实践。 我的建议是使用MessageBodyReaderreadFrom方法中执行validation。 下面是一个消息体阅读器示例,为简单起见,它是非通用的。

我也很想找到做json数据validation的最佳框架。 因为我使用jackson框架(版本1.8.5)在json和java之间进行编组和解组,所以如果这个框架提供json数据validationfunction会很好。 不幸的是我找不到与jackson这样做的可能性。 最后,我使用了https://github.com上提供的json-schema-validator 。 我使用的版本是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
{ 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
type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { final String jsonData = getStringFromInputStream(entityStream); System.out.println(jsonData); InputStream isSchema = new FileInputStream(jsonSchemaFileAsString); String jsonSchema = getStringFromInputStream(isSchema); /https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* Perform JSON data validation against schema https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/*/ validateJsonData(jsonSchema, jsonData); /https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* Convert stream to data entity https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/*/ ObjectMapper m = new ObjectMapper(); Address addr = m.readValue(stringToStream(jsonData), Address.class); return addr; } /https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/*https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* Validate the given JSON data against the given JSON schema https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* @param jsonSchema https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* as String https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* @param jsonData https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* as String https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* @throws MessageBodyReaderValidationException https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* in case of an error during validation process https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/*/ 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); } } /https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/*https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* Taken from www.mkyong.com https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* @param is https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* {@link InputStream} https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/* @return Stream content as String https://stackoverflow.com/questions/18154983/how-do-i-validate-incoming-json-data-inside-a-rest-service/*/ 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")); } }
 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()); } }