serialize example deserialize java json rest jackson required

java - example - Aplicar campo no nulo en objeto JSON



map json to java object spring (4)

Nuestra API REST recibe una entrada de algunos objetos JSON donde se requiere que algunos campos no sean nulos. Pueden ser String / Integer o incluso pueden ser otras instancias de clase como referencia.

Estamos tratando de encontrar una manera de hacer que esos campos no sean nulos, en lugar de la forma correcta de verificación nula en la api. Corriente:

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

Lo que queremos tener es algo como:

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

Hemos intentado 3 cosas:

  • Actualice a jackson 2.0.6 y use la anotación com.fasterxml.jackson.annotation.JsonProperty. Pero esto parece que no funciona. Encontré esas referencias: http://jira.codehaus.org/browse/JACKSON-767

  • Extender JsonDeserializer para verificar nulo 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;

  • Escribimos nuestra propia anotación @Required e intentamos verificar con ResourceFilter, pero parece que no puedo obtener el objeto real de ContainerRequest e incluso si pudiéramos, no estamos seguros de cómo realizar una comprobación profunda de la 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 apreciados.


Puede imponer la validación not null utilizando una combinación de la biblioteca JSON de Jackson y la javax.validation junto con el paquete de validación Hibernate.

Si está utilizando Maven, estas son las dependencias que puede usar:

<dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson-version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson-version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson-version}</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.validation/validation-api --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate-validator.version}</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator-annotation-processor</artifactId> <version>${hibernate-validator.version}</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency> </dependencies>

Luego, su código tendrá que convertir algo de JSON en su objeto anotado y tendrá que validar el objeto utilizando javax.validation.Validator . Aquí hay un ejemplo de código que muestra cómo se puede hacer esto (vea el método de validate relevante):

public class ShareLocationService { private ObjectMapper mapper = new ObjectMapper(); private ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); // Materialize the Java object which contains the validation annotations public ShareLocation readFrom(String json) throws IOException { return mapper.readerFor(ShareLocation.class).readValue(json); } // validate and collect the set of validations public Set<String> validate(String json) throws IOException { ShareLocation shareMyLocation = readFrom(json); Validator validator = factory.getValidator(); Set<ConstraintViolation<ShareLocation>> violations = validator.validate(shareMyLocation); return violations.stream().map(Object::toString).collect(Collectors.toSet()); } }

Aquí hay una clase de muestra usando las anotaciones de validación:

public class ShareLocation { @JsonProperty("Source") @NotNull private String source; @JsonProperty("CompanyCode") private String companyCode; @JsonProperty("FirstName") private String firstName; @JsonProperty("LastName") private String lastName; @JsonProperty("Email") private String email; @JsonProperty("MobileNumber") private String mobileNumber; @JsonProperty("Latitude") @NotNull private Double latitude; @JsonProperty("Longitude") @NotNull private Double longitude; @JsonProperty("LocationDateTime") @NotNull private String locationDateTime;




JAX-RS separa bastante bien la deserialización de la validación, es decir, Jackson no tiene ningún mecanismo para imponer que los valores non-null , etc. En su lugar, puede usar BeanValidation para eso:

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

Para más detalles, vaya here .