Get field name when javax.validation.ConstraintViolationException is thrown

When the PathVariable name fails the test, a javax.validation.ConstraintViolationException is thrown. Is there a way to get the parameter name in javax.validation.ConstraintViolationException throwing?

@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; } 
+14
spring bean validation
source share
4 answers

The following exception handler shows how it works:

 @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); } 

You can get an invalid value (name) with

  constraintViolation.getInvalidValue() 

You can access the property name 'name' with

 constraintViolation.getPropertyPath() 
+11
source share

use this method (e.g. instance of 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
source share

If you check the return value of getPropertyPath() , you will find it Iterable<Node> , and the last element of the iterator is the field name. The following code works for me:

 // 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(); } 
+3
source share

I had the same issue, but also got "sayHi.arg0" from getPropertyPath. I decided to add the message in NotNull annotations, as they were part of our public API. How:

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

you can get a message by calling

ConstraintViolation # GetMessage ()

+2
source share

All Articles