I am using Spring Boot to create a POST request and I need to validate the request body based on user inputs. However, when the user inputS an invalid data type, the response shows nothing, just 400 bad request
status. Can I add a message to show the user which field is an invalid data type?
For example: Here is my controller:
@RestController
@RequestMapping("/api/foo")
public class FooController {
@PostMapping("/save")
public void postFoo(@Valid @RequestBody Foo foo) {
// do somethings
}
}
And here is my Foo class:
public class Foo {
@NotBlank
private String name;
private Integer age;
// getter/setter
}
So now I post a request as below:
{
"name": "Foo Name",
"age": "A String"
}
The server will respond with the status 400 Bad request
without any message. How can I put my message such as Age must be an integer
.
Until now I only have a solution that changes Age to String and adds a @Pattern validation annotation.
public class Foo {
@NotBlank
private String name;
@Pattern(regexp = "[0-9]*", message = "Age must be an intege")
private String age;
// getter/setter
}
Thanks, everybody. I found a way to add messages and respond to users can aware of the error by using ControllerAdvice
and overriding the handleHttpMessageNotReadable
method as example below:
@ControllerAdvice
public class ErrorHandlerConfig extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
if (ex.getCause() instanceof InvalidFormatException) {
InvalidFormatException iex = (InvalidFormatException) ex.getCause();
List<Map<String, String>> errors = new ArrayList<>();
iex.getPath().forEach(reference -> {
Map<String, String> error = new HashMap<>();
error.put(reference.getFieldName(), iex.getOriginalMessage());
errors.add(error);
});
return handleExceptionInternal(ex, errors, new HttpHeaders(), apiError.getStatus(), request);
}
return super.handleHttpMessageNotReadable(ex, headers, status, request);
}
}
The response will be:
[
{
"testId": "Cannot deserialize value of type `java.lang.Long` from String \"accm\": not a valid Long value"
}
]