I've a very simple spring boot controller with param validation.
@GetMapping(value = "/test/{p}")
@NonNull
public String test(@PathVariable(value = "p", required = true) @Valid @Size(min = 2) String t) {
return "";
}
if I send any string longer than 2 letters it returns 200, but if I send any 1 letter string it returns 500. I would like the return code for failed validation be 400 which makes much more sense... how can i set the status code for constraint validation fail on spring boot controller
CodePudding user response:
You can make use of ExceptionHandler and/or ControllerAdvice
Here's an example of ExceptionHandler that you can include in your existing Controller:
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<List<String>> handleConstraintViolationException(ConstraintViolationException cve) {
List<String> errorMessages = cve.getConstraintViolations()
.stream()
.map(ConstraintViolation::getMessage)
.toList();
return new ResponseEntity<>(errorMessages, HttpStatus.BAD_REQUEST);
}
Note that you probably want to create a better response model rather than just a List<String>
shown above.
Some further info: https://medium.com/@jovannypcg/understanding-springs-controlleradvice-cd96a364033f
CodePudding user response:
I agree with the @ExceptionHandler
solution proposed by Tim. I've used the same approach in all my projects.
Besides this, I can also recommend looking into the Zalando Problem library, which has out-of-the-box support for handling ConstraintViolationException
and many others. It also provides a unified format of responses for the whole application with any necessary customizations. This is a simple guide that shows the basic examples of usage — A Guide to the Problem Spring Web Library.
Regarding your comment saying that assigning the 400 status will create a total mess because this exception may also be thrown on the repository level. I think that it's a bad practice to return to the client responses with DB-level exception messages or any other internal messages. It will be better to implement handlers for such exceptions by rethrowing problem-specific exceptions with clear messages.
And even if you wouldn't consider doing that, why do you think that returning 400 status for ConstraintViolationException
which was thrown on the repository level is a bad idea? Such exceptions usually mean that you have violated some DB constraint, which is just another type of validation. Such exceptions will always be caused by the incorrect data, supplied to the application by a client. Don't you think that it makes sense to treat such errors as bad requests?