validator example bean jackson bean-validation hibernate-validator

jackson - bean - javax.validation example



Hibernate Validator y Jackson: ¿Cómo usar el valor @JsonProperty como ConstraintViolation PropertyPath? (2)

Desafortunadamente no hay una manera fácil de hacerlo. Pero aquí hay algunas ideas que pueden ayudarte:

Revisar violaciones de restricciones

Desde ConstraintViolationException , puede obtener un conjunto de ConstraintViolation , que expone el contexto de violación de restricciones:

Desde la ruta de la propiedad, puede obtener el nodo hoja:

Path propertyPath = constraintViolation.getPropertyPath(); Optional<Path.Node> leafNodeOptional = StreamSupport.stream(propertyPath.spliterator(), false).reduce((a, b) -> b);

Luego verifique si el tipo del nodo es PROPERTY y obtenga su nombre:

String nodeName = null; if (leafNodeOptional.isPresent()) { Path.Node leafNode = leafNodeOptional.get(); if (ElementKind.PROPERTY == leafNode.getKind()) { nodeName = leafNode.getName(); } }

Introspección de una clase con Jackson

Para obtener las propiedades JSON disponibles de la clase de hoja de frijol, puede introspectarlo con Jackson (consulte esta respuesta y esta respuesta para obtener más detalles):

Class<?> beanClass = constraintViolation.getLeafBean().getClass(); JavaType javaType = mapper.getTypeFactory().constructType(beanClass); BeanDescription introspection = mapper.getSerializationConfig().introspect(javaType); List<BeanPropertyDefinition> properties = introspection.findProperties();

A continuación, filtre las propiedades comparando el nombre del nodo hoja con el nombre del Field desde BeanPropertyDefinition :

Optional<String> jsonProperty = properties.stream() .filter(property -> nodeName.equals(property.getField().getName())) .map(BeanPropertyDefinition::getName) .findFirst();

¿Usando JAX-RS?

Con JAX-RS (si lo está usando), puede definir un ExceptionMapper para manejar los ConstraintViolationException :

@Provider public class ConstraintViolationExceptionMapper implements ExceptionMapper<ConstraintViolationException> { @Override public Response toResponse(ConstraintViolationException exception) { ... } }

Para usar ObjectMapper en su ExceptionMapper , puede proporcionarle un ContextResolver<T> :

@Provider public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> { private final ObjectMapper mapper; public ObjectMapperContextResolver() { mapper = createObjectMapper(); } @Override public ObjectMapper getContext(Class<?> type) { return mapper; } private ObjectMapper createObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.INDENT_OUTPUT, true); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; } }

Inyecte la interfaz de Providers en su ExceptionMapper :

@Context private Providers providers;

ContextResolver<T> su ContextResolver<T> y luego obtenga la instancia de ObjectMapper :

ContextResolver<ObjectMapper> resolver = providers.getContextResolver(ObjectMapper.class, MediaType.WILDCARD_TYPE); ObjectMapper mapper = resolver.getContext(ObjectMapper.class);

Si está interesado en obtener nombres de @XxxParam , consulte esta respuesta .

Digamos que tengo un POJO simple como el que se indica a continuación con anotaciones de Jackson 2.1 e Hibernate Validator 4.3.1:

final public class Person { @JsonProperty("nm") @NotNull final public String name; public Person(String name) { this.name = name; } }

Y envío JSON como tal a un servicio web:

{"name": null}

Hibernate cuando informa que ConstraintViolation usa el identificador de miembro de la clase "nombre" en lugar del valor de la anotación JsonProperty. ¿Alguien sabe si es posible hacer que el Validador de Hibernate observe la anotación de la clase y usar ese valor en su lugar?


No, eso no es posible. Hibernate Validator 5 (Bean Validation 1.1) tiene la noción de ParameterNameProvider s que devuelve los nombres a los que se informa en caso de que se violen las restricciones de los parámetros del método, pero no hay nada comparable para las limitaciones de la propiedad.