Does Spring throw HttpRequestMethodNotSupportedException
when a request body is not valid and @Valid
(or @Validated
) is used? I really expected MethodArgumentNotValidException
.
Details: I have a small REST server built on Spring-Boot version 2.2.4. One of the methods looks like this:
@PostMapping("/yapp")
public Yapp kickYapp(@Validated @RequestBody YappDescriptor yappDescriptor) {
logger.debug("kickYapp descriptor {}", yappDescriptor);
doWork(yappDescriptor);
}
The YappDescriptor has annotations like "required" but nothing for valid values, ranges, etc. When I POST a well-formed JSON object with values for all the required fields as defined in the YappDescriptor POJO, the Spring controller method is found and invoked as expected.
I tried a couple error scenarios:
1) If I POST a well-formed JSON object that has only null values for the expected fields, the method is found and entered as expected.
2) If I POST a well-formed JSON object with a key that does not match any of the POJO's fields, the method is NOT found and entered. In watching class org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
I see the exception is HttpRequestMethodNotSupportedException
and the server answers 405 "Request method 'POST' not supported".
In this controller class, kickYapp
is the only POST-mapped method at the specified path, so I think that answer is pretty confusing. Altho I'm definitely sending a bad request (unexpected data), I am surprised my POST-mapped method is not found and invoked.
This post Validating if request body in HTTP POST request is null in Spring Boot controller suggests I should be seeing HttpMessageNotReadableException
which would be helpful, but I never get that exception.
Many other questions on SO seem to be about enabling validation of request bodies, like Spring 4.1.7 validate request body , but I seem to be past that.
Thanks in advance for helping me understand this behavior and maybe improve the server to help my users discover their errors more easily (which saves me time :). Thought I could maybe extend that method to accept a BindingResult parameter and report errors that way, but that's a non-starter if the controller method is never entered.
Update to respond to comments: yes I could have used @Valid. In my tests annotation @javax.validation.Valid and @org.springframework.validation.annotation.Validated have the same effect, both turned on validation of the RequestBody parameter.