I have a rest application (no forms, etc.) with the following request mapping for the input:
public class User {
@Valid
private List<Contact> contact;
public List<Contact> getContact() {
return contact;
}
public void setContact(List<Contact> contact) {
this.contact = contact;
}
}
public class Contact {
@Size(max = 20, message = ErrorMessages.E_MAIL_INVALID_LENGTH)
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
The validation works but I also want to include the index of the item where it violated a constraint:
actual input and response:
{
"contact" :[{
"email": "tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com"
}, {
"email": "tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com"
}
]
}
{
"timestamp": "2022-06-16T00:43:50.878+00:00",
"status": 400,
"errors": [
"E-mail address 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long",
"E-mail address 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long"
]
}
for the response I want to generate I want to put the index like this:
E-Mail address 1 E-Mail address 2
{
"timestamp": "2022-06-16T00:43:50.878+00:00",
"status": 400,
"errors": [
"E-mail address 1: 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long",
"E-mail address 2: 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long"
]
}
UPDATE
I got it to work by using the following code in my controller ()
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", new Date());
body.put("status", HttpStatus.BAD_REQUEST);
Map<String, String> errors = new HashMap<>();
List<ObjectError> errorList = ex.getBindingResult().getAllErrors();
errorList.forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
body.put("errors", errors);
return body;
}
output is:
{
"timestamp": "2022-06-16T01:49:04.832+00:00",
"status": "BAD_REQUEST",
"errors": {
"contact[1].email": "E-mail address 'tesaaaaaaaaaaaaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long",
"contact[0].email": "E-mail address 'tesaaaaaaaaaaasdasdasdaaaaaaaaaaaaaaaaat@test.com' must be between 0 and 20 characters long"
}
}
I just need to reverse the order of the error messages and it's all good.
You can try using a counter variable, which can work as an index for each error.
First create a counter variable before the forEach
then use it inside the forEach
.
Here is the updated Controller'a code.
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", new Date());
body.put("status", HttpStatus.BAD_REQUEST);
Map<String, String> errors = new HashMap<>();
List<ObjectError> errorList = ex.getBindingResult().getAllErrors();
int counter = 0;
errorList.forEach((error) -> {
counter++;
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
String index = String.valueOf(counter);
errors.put(index, fieldName, errorMessage);
});
body.put("errors", errors);
return body;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.