The @RequestBody javadoc states
Annotation indicating a method parameter should be bound to the body
of the web request.
It uses registered instances of HttpMessageConverter to deserialize the request body into an object of the annotated parameter type.
And the @RequestParam javadoc states
Annotation which indicates that a method parameter should be bound to
a web request parameter.
-
Spring binds the body of the request to the parameter annotated with
@RequestBody. -
Spring binds request parameters from the request body (url-encoded parameters) to your method parameter. Spring will use the name of the parameter, ie.
name, to map the parameter. -
Parameters are resolved in order. The
@RequestBodyis processed first. Spring will consume all theHttpServletRequestInputStream. When it then tries to resolve the@RequestParam, which is by defaultrequired, there is no request parameter in the query string or what remains of the request body, ie. nothing. So it fails with 400 because the request can’t be correctly handled by the handler method. -
The handler for
@RequestParamacts first, reading what it can of theHttpServletRequestInputStreamto map the request parameter, ie. the whole query string/url-encoded parameters. It does so and gets the valueabcmapped to the parametername. When the handler for@RequestBodyruns, there’s nothing left in the request body, so the argument used is the empty string. -
The handler for
@RequestBodyreads the body and binds it to the parameter. The handler for@RequestParamcan then get the request parameter from the URL query string. -
The handler for
@RequestParamreads from both the body and the URL query String. It would usually put them in aMap, but since the parameter is of typeString, Spring will serialize theMapas comma separated values. The handler for@RequestBodythen, again, has nothing left to read from the body.