What is difference between @RequestBody and @RequestParam?

Manoj Singh picture Manoj Singh · Jan 20, 2015 · Viewed 111k times · Source

I have gone through the Spring documentation to know about @RequestBody, and they have given the following explanation:

The @RequestBody method parameter annotation indicates that a method parameter should be bound to the value of the HTTP request body. For example:

@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
  writer.write(body);
}

You convert the request body to the method argument by using an HttpMessageConverter. HttpMessageConverter is responsible for converting from the HTTP request message to an object and converting from an object to the HTTP response body.

DispatcherServlet supports annotation based processing using the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter. In Spring 3.0 the AnnotationMethodHandlerAdapter is extended to support the @RequestBody and has the following HttpMessageConverters registered by default:

...

but my confusion is the sentence they have written in the doc that is

The @RequestBody method parameter annotation indicates that a method parameter should be bound to the value of the HTTP request body.

What do they mean by that? Can anyone provide me an example?

The @RequestParam definition in spring doc is

Annotation which indicates that a method parameter should be bound to a web request parameter. Supported for annotated handler methods in Servlet and Portlet environments.

I have become confused between them. Please, help me with an example on how they are different from each other.

Answer

Patrik Bego picture Patrik Bego · Oct 6, 2015

@RequestParam annotated parameters get linked to specific Servlet request parameters. Parameter values are converted to the declared method argument type. This annotation indicates that a method parameter should be bound to a web request parameter.

For example Angular request for Spring RequestParam(s) would look like that:

$http.post('http://localhost:7777/scan/l/register?username="Johny"&password="123123"&auth=true')
      .success(function (data, status, headers, config) {
                        ...
                    })

Endpoint with RequestParam:

@RequestMapping(method = RequestMethod.POST, value = "/register")
public Map<String, String> register(Model uiModel,
                                    @RequestParam String username,
                                    @RequestParam String password,
                                    @RequestParam boolean auth,
                                    HttpServletRequest httpServletRequest) {...

@RequestBody annotated parameters get linked to the HTTP request body. Parameter values are converted to the declared method argument type using HttpMessageConverters. This annotation indicates a method parameter should be bound to the body of the web request.

For example Angular request for Spring RequestBody would look like that:

$scope.user = {
            username: "foo",
            auth: true,
            password: "bar"
        };    
$http.post('http://localhost:7777/scan/l/register', $scope.user).
                        success(function (data, status, headers, config) {
                            ...
                        })

Endpoint with RequestBody:

@RequestMapping(method = RequestMethod.POST, produces = "application/json", 
                value = "/register")
public Map<String, String> register(Model uiModel,
                                    @RequestBody User user,
                                    HttpServletRequest httpServletRequest) {... 

Hope this helps.