web-dev-qa-db-fra.com

Récupère le nom du champ quand une exception javax.validation.ConstraintViolationException est levée

Lorsque la variable 'nom' PathVariable ne passe pas la validation, une exception javax.validation.ConstraintViolationException est levée. Existe-t-il un moyen de récupérer le nom du paramètre dans l'exception javax.validation.ConstraintViolationException renvoyée?

@RestController
@Validated
public class HelloController {

@RequestMapping("/hi/{name}")
public String sayHi(@Size(max = 10, min = 3, message = "name should    have between 3 and 10 characters") @PathVariable("name") String name) {
  return "Hi " + name;
}
9
Josh

Le gestionnaire d'exceptions suivant montre comment cela fonctionne:

@ExceptionHandler(ConstraintViolationException.class)

ResponseEntity<Set<String>> handleConstraintViolation(ConstraintViolationException e) {
    Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();

Set<String> messages = new HashSet<>(constraintViolations.size());
messages.addAll(constraintViolations.stream()
        .map(constraintViolation -> String.format("%s value '%s' %s", constraintViolation.getPropertyPath(),
                constraintViolation.getInvalidValue(), constraintViolation.getMessage()))
        .collect(Collectors.toList()));

return new ResponseEntity<>(messages, HttpStatus.BAD_REQUEST);

}

Vous pouvez accéder à la valeur invalide (nom) avec 

 constraintViolation.getInvalidValue()

Vous pouvez accéder au nom de la propriété 'nom' avec 

constraintViolation.getPropertyPath()

utilisez cette méthode (par exemple, instance ConstraintViolationException):

Set<ConstraintViolation<?>> set =  ex.getConstraintViolations();
    List<ErrorField> errorFields = new ArrayList<>(set.size());
    ErrorField field = null;
    for (Iterator<ConstraintViolation<?>> iterator = set.iterator();iterator.hasNext(); ) {
        ConstraintViolation<?> next =  iterator.next();
       System.out.println(((PathImpl)next.getPropertyPath())
                .getLeafNode().getName() + "  " +next.getMessage());


    }
4
zui-coding

J'ai eu le même problème, mais j'ai également reçu "sayHi.arg0" de getPropertyPath. J'ai choisi d'ajouter un message aux annotations NotNull, car elles faisaient partie de notre API publique. Comme:

 @NotNull(message = "timezone param is mandatory")

vous pouvez obtenir le message en appelant 

ConstraintViolation # getMessage ()

3
Pepster

Si vous inspectez la valeur de retour de getPropertyPath(), vous constaterez qu'il s'agit d'un Iterable<Node> et que le dernier élément de l'itérateur est le nom du champ. Le code suivant fonctionne pour moi:

// I only need the first violation
ConstraintViolation<?> violation = ex.getConstraintViolations().iterator().next();
// get the last node of the violation
String field = null;
for (Node node : violation.getPropertyPath()) {
    field = node.getName();
}
0
leowang