Saltar al contenido

¿Cómo valido los datos JSON entrantes dentro de un servicio REST?

Te sugerimos que revises esta respuesta en un entorno controlado antes de enviarlo a producción, un saludo.

Solución:

Busqué las mejores prácticas para aplicar la validación de los datos json entrantes en un servicio RESTful. Mi sugerencia es utilizar un MessageBodyReader que realiza la validación dentro del readFrom método. A continuación, se muestra un ejemplo de lector de cuerpo de mensaje que no es genérico en aras de la simplicidad.

También estaba interesado en encontrar el mejor marco para realizar la validación de datos json. Debido a que uso el marco jackson (versión 1.8.5) para calcular y deshacer entre json y java, hubiera sido bueno si este marco proporcionara una funcionalidad de validación de datos json. Desafortunadamente, no pude encontrar ninguna posibilidad de hacer esto con jackson. Finalmente lo hice funcionar con el json-schema-validator disponible en https://github.com. La versión que uso es 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); /* * 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 www.mkyong.com * * @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"));

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(String[] arr)
       String jsonData = ""name": "prem"";
       String jsonSchema = ""; //Schema we can generate 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());
    


Si te sientes motivado, tienes la libertad de dejar un tutorial acerca de qué le añadirías a este escrito.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *