Reputation: 1227
I'm using Hibernate Validator 4.2.0.Final and I'm looking for the simplest way to include class field name in my error message.
What I found is the following thread Using a custom ResourceBundle with Hibernate Validator. According to this I should create my custom annotation for each constraint annotation adding one property to each one.
Is there a cleaner way to achieve this?
The following code:
@Size(max = 5)
private String myField;
produces default error: size must be between 0 and 5.
I would like it to be: myField size must be between 0 and 5.
Upvotes: 30
Views: 26277
Reputation: 177
A better way so that internationalization is supported.
//in ValidationMessages.properties
app.FieldName=MyField
app.validation.size.msg=size must be between {min} and {max} but provided ${validatedValue}
@Size(min=10, max=15, message = "{app.FieldName}"+" "+ "{app.validation.size.msg}") private String myField;
Upvotes: 1
Reputation: 422
If validating a REST call in a controller and using a controller advice, you can combine field and default message from MethodArgumentNotValidException like this:
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception, HttpHeaders headers, HttpStatus status, WebRequest request) {
String errorMessage = exception
.getBindingResult()
.getFieldErrors()
.stream()
.map(fieldError -> fieldError.getField() + " " + fieldError.getDefaultMessage())
.collect(Collectors.joining(", "));
return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
}
Upvotes: 1
Reputation: 93
If your messages are in .properties
file then there is no interpolation variable for accessing property name but one way you can achieve that is
//in ValidationMessages.properties
app.validation.size.msg=size must be between {min} and {max}
@Size(min=10, max=15, message = "myField {app.validation.size.msg})
private String myField;
OR
//in ValidationMessages.properties
app.validation.size.msg=size must be between {min} and {max} but provided ${validatedValue}
@Size(min=10, max=15, message = "myField {app.validation.size.msg})
private String myField;
Reference: message interpolation
Upvotes: 8
Reputation: 166
use this method(ex is ConstraintViolationException instance):
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());
}
Upvotes: 0
Reputation: 1346
I put every field validation message into the properties file, like this:
field.student.name.size.message = Student name size is not valid.
and in the bean, use it like this:
@Size(max = 5, message = "${field.student.name.size.message}")
private String myField;
I know it isn't a perfect solution, but I also don't find a better way.
Upvotes: 3
Reputation: 1003
You can get the name of the field with the getPropertyPath()
method from the ConstraintViolation
class.
A good default error message can be:
violation.getPropertyPath() + " " + violation.getMessage();
Which will give you "foo may not be null", or "foo.bar may not be null" in the case of nested objects.
Upvotes: 37
Reputation: 1227
For all those who are looking for a way to access class inside your validator. Putting hibernate annotating on a class level instead of variable level gives you access to a class object (assuming that you have defined a custom validator).
public class myCustomValidator implements ContraintValidator <MyAnnotation, MyAnnotatedClass> {
public void initialize (...){ ... };
public boolean isValid (MyAnnotatedClass myAnnotatedClass) {
// access to elements of your myAnnotatedClass
}
}
Upvotes: 0
Reputation: 6273
use oval this has good number of annotations and possible ways to display messages.
Upvotes: 0
Reputation: 22710
I am not aware of any generic way but you can define custom error message and include field name in it.
@Size(max = 5, message = "myField size must be between 0 and 5")
private String myField;
Upvotes: 2