我搜索了最佳实践,以对进入RESTful服务的传入json数据实施验证。我的建议是使用
MessageBodyReader在
readFrom方法内部执行验证的。下面有一个message-
body-reader示例,为简单起见,它是非通用的。
我也对寻找用于执行json数据验证的最佳框架感兴趣。因为我使用jackson框架(版本1.8.5)在json和java之间进行编组和解编组,所以如果该框架提供json数据验证功能,那就太好了。不幸的是,我找不到与杰克逊一起做这件事的任何可能性。最后,我将它与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.prehaus.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); validateJsonData(jsonSchema, jsonData); ObjectMapper m = new ObjectMapper(); Address addr = m.readValue(stringToStream(jsonData), Address.class); return addr; } 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); } } 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")); }}


