2012-10-10 39 views
15

Nuestra API REST recibe algunos objetos JSON de entrada, donde se requiere que algunos campos no sean nulos. Esos pueden ser String/Integer o incluso podría ser alguna otra instancia de clase como referencia.Aplicar el campo no nulo en el objeto JSON

Estamos tratando de encontrar una forma de hacer cumplir esos campos para que no sea nula, en lugar de la forma corrent para la verificación nula en la API. actual:

 

    if (myObject.getSomeOtherObject() == null) 
    throw new SomeException(); 

Lo que queremos es que algo como:

 

    class MyObject{ 
    @Required 
    OtherObject someOtherObject; 
    ... 
    } 

Hemos intentado 3 cosas:

  • actualiza a 2.0.6 Jackson y el uso de la anotación com .fasterxml.jackson.annotation.JsonProperty Pero esto simplemente no funciona. encontradas esas referencias: http://jira.codehaus.org/browse/JACKSON-767

  • Ampliación JsonDeserializer para comprobar nula, pero el problema es que ni siquiera se ejecuta en la entrada nula.

 

    public class NotNullDeserializer<T> extends JsonDeserializer<T> { 

     @Override 
     public T deserialize(JsonParser jsonparser, DeserializationContext deserializationcontext) throws IOException, JsonProcessingException { 

      ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass(); 
      Class type = (Class) superClass.getActualTypeArguments()[0]; 

      T t = jsonparser.readValueAs(type); 

      if (t == null){ 
       String classNameField = type.getName(); 
       String field = jsonparser.getCurrentName(); 
       throw new WrongInputException("The field '"+field+"' of type '"+classNameField+"' should not be null."); 
      } 

      return t; 
     } 

    } 

    public class NotNullAddressDeserializer extends NotNullDeserializer<Address> { 

    } 

    @JsonDeserialize(using=NotNullAddressDeserializer.class) 
     Address to; 

  • escribir nuestra propia anotación @Required y tratando de comprobar con ResourceFilter, pero parece que no puedo conseguir el objeto real de la ContainerRequest e incluso si pudiéramos, no está seguro de cómo ejecutar cheque profunda de referencia nula en object.otherObject.someObject.fieldNotNullable
 

    private class Filter implements ResourceFilter, ContainerRequestFilter { 

     private final ArrayList requiredParameters; 

     protected Filter() { 
      requiredParameters = null; 
     } 

     protected Filter(ArrayList requiredParameters) { 
      this.requiredParameters = requiredParameters; 
     } 

     @Override 
     public ContainerRequestFilter getRequestFilter() { 
      return this; 
     } 

     @Override 
     public ContainerResponseFilter getResponseFilter() { 
      return null; 
     } 


     @Override 
     public ContainerRequest filter(ContainerRequest request) { 
      if (requiredParameters != null && requiredParameters.size() > 0) { 
       MultivaluedMap params = request.getQueryParameters(); 
       params.putAll(request.getFormParameters()); 
       StringBuffer missingParams = new StringBuffer(); 
       for (String reqParam : requiredParameters) { 
        List paramValues = params.get(reqParam); 
        if (paramValues == null || paramValues != null && paramValues.size() == 0) 
         missingParams.append(reqParam + ","); 
       } 
       if (missingParams.length() > 0) 
        throw new WrongInputException("Required parameters are missing: " + missingParams); 
      } 
      return request; 
     } 
    } 


Cualquier ayuda y conocimientos apreciado.

Respuesta

16

JAX-RS separa bastante bien la deserialización de la validación, es decir, Jackson tiene por diseño sin mecanismo para forzar valores para ser non-null, etc. En su lugar, puede usar BeanValidation para t sombrero:

  1. Agregue una dependencia a javax.validation:validation-api en provided alcance.
  2. Agregue la anotación javax.validation.constraints.NotNull a su campo.

Para obtener más información, vaya here.

+0

Aunque esta es una vieja pregunta, la respuesta es buena :) ¡Gracias! Aceptado. – urir

+1

error en el nombre del paquete: restricciones – Bax

1

@Required es una anotación de marco de primavera para granos inyectados, por lo que yo diría que no lo use para este propósito.

Puede utilizar éste en su lugar:

http://robaustin.wikidot.com/annotations-and-notnull

@NotNull String myString;

Para los controles de tiempo de ejecución, trate http://code.google.com/p/notnullcheckweaver/

+0

'@ required' hice referencia era nuestra propia anotación. De todos modos, gracias y voy a intentar su consejo ahora, solo - ¿qué jar necesito para 'core.validation. *' Imports? – urir

+0

La anotación en el enlace es para 'esta anotación está destinada a ser utilizada por herramientas de análisis estático'. Pero necesito esto para la validación API estricta en tiempo de ejecución. Gracias :) – urir

+0

ver mi edición anterior, entonces. –

2

Puede utilizar JSON-esquema que se puede expresar muchas limitaciones en los campos JSON con él: http://json-schema.org/

A continuación, puede generar a partir del esquema de las clases Java con @NotNull JSR 303 anotaciones y utilizar la validación de frijol en el objeto . Funciona con Jackson de forma nativa, por lo que no debería tener ningún problema.

Por ejemplo, puede utilizar el plugin de Maven para hacerlo: http://wiki.jsonschema2pojo.googlecode.com/git/site/0.3.7/generate-mojo.html

Cuestiones relacionadas