Using HTTP dev client with Post request and Content-Type application/x-www-form-urlencoded
URL: localhost:8080/SpringMVC/welcome
Body: name=abc
@RequestMapping(method = RequestMethod.POST) public String printWelcome(@RequestBody String body, Model model) { model.addAttribute("message", body); return "hello"; } // Gives body as 'name=abc' as expected URL: localhost:8080/SpringMVC/welcome
In Body - name=abc
@RequestMapping(method = RequestMethod.POST) public String printWelcome(@RequestParam String name, Model model) { model.addAttribute("name", name); return "hello"; } // Gives name as 'abc' as expected URL: localhost:8080/SpringMVC/welcome
Body: name=abc
@RequestMapping(method = RequestMethod.POST) public String printWelcome( @RequestBody String body, @RequestParam String name, Model model) { model.addAttribute("name", name); model.addAttribute("message", body); return "hello"; } // HTTP Error Code 400 - The request sent by the client was syntactically incorrect. URL: localhost:8080/SpringMVC/welcome
Body: name=abc
@RequestMapping(method = RequestMethod.POST) public String printWelcome( @RequestParam String name, @RequestBody String body, Model model) { model.addAttribute("name", name); model.addAttribute("message", body); return "hello"; } // No Error. Name is 'abc'. body is empty URL: localhost:8080/SpringMVC/welcome?name=xyz
Body: name=abc
@RequestMapping(method = RequestMethod.POST) public String printWelcome( @RequestBody String body, @RequestParam String name, Model model) { model.addAttribute("name", name); model.addAttribute("message", body); return "hello"; } // name is 'xyz' and body is 'name=abc' @RequestMapping(method = RequestMethod.POST) public String printWelcome( @RequestParam String name, @RequestBody String body, Model model) { model.addAttribute("name", name); model.addAttribute("message", body); return "hello"; } // name = 'xyz,abc' body is empty Can someone explain this behaviour?
nothing. So it fails with 400 because the request can't be correctly handled by the handler method.
If you don't add @RequestBody it will insert null values (should use), no need to use @ResponseBody since it's part of @RestController.
Difference between @RequestParam vs @RequestBody For example, the below getOrders handler method of the Orders controller handles all the incoming HTTP GET requests with path /orders . The request param maps the query param since to the method parameter sinceDate .
the conversion is handled automatically.
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 @RequestBody is processed first. Spring will consume all the HttpServletRequest InputStream. When it then tries to resolve the @RequestParam, which is by default required, 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 @RequestParam acts first, reading what it can of the HttpServletRequest InputStream to map the request parameter, ie. the whole query string/url-encoded parameters. It does so and gets the value abc mapped to the parameter name. When the handler for @RequestBody runs, there's nothing left in the request body, so the argument used is the empty string.
The handler for @RequestBody reads the body and binds it to the parameter. The handler for @RequestParam can then get the request parameter from the URL query string.
The handler for @RequestParam reads from both the body and the URL query String. It would usually put them in a Map, but since the parameter is of type String, Spring will serialize the Map as comma separated values. The handler for @RequestBody then, again, has nothing left to read from the body.
It's too late to answer this question, but it could help for new readers, It seems version issues. I ran all these tests with spring 4.1.4 and found that the order of @RequestBody and @RequestParam doesn't matter.
body= "name=abc", and name = "abc" body ="name=abc", name = "xyz,abc" If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With