0

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.

chrisinmtown
  • 3,571
  • 3
  • 34
  • 43

1 Answers1

0

why not use @Valid? like so:

public ResponseEntity<SalaryDto> update(@Valid @RequestBody SalaryDto subject)

and don't forget to use javax.validation validation annotations in your request body object

Omar Ajmi
  • 180
  • 1
  • 13
  • Yes alternately I could have used Valid. Annotations javax.validation.Valid and org.springframework.validation.annotation.Validated seem to have the same effect. Validation is documented as "Variant of JSR-303's {link javax.validation.Valid}" – chrisinmtown May 20 '20 at 00:24
  • @chrisinmtown so that answers your question i guess – Omar Ajmi May 20 '20 at 00:25
  • .OmarAjmi, thanks but no, my question remains, why no-such-method, why not argument-not-valid? – chrisinmtown May 20 '20 at 00:29