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
}
CodePudding user response:
In your post method signature, you can make use of Response Entity class to show some exception message that is to be returned to the user, along with some status code .
CodePudding user response:
You need to implement error handling mechanism.
In your error handler you need to catch all exceptions and return error response. Here is an example based on Controller level ExceptionHandling
public class FooController{
//...
@ResponseStatus(value=HttpStatus.BAD_REQUEST)
@ExceptionHandler({ CustomException1.class, CustomException2.class })
public ErrorResponse handleException() {
//
}
}
Here in ErrorResponse model you can set error code and message according to exception and via ResponseStatus you can assign http errro code
However this his approach has a major drawback: The @ExceptionHandler annotated method is only active for that particular Controller, not globally for the entire application.
To globally handle exception you can use ControllerAdvice. Here is a good article on overall error handling mechanism
CodePudding user response:
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"
}
]