Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the use of @ModelAttribute and @RequestAttribute annotations in Spring MVC

I am pretty new in Spring MVC. Currently I am studying the Spring MVC Showcase, that demonstrates the features of the Spring MVC web framework.

I have some problem to understand how Custom Resolvable Web Arguments are handled in this example.

In practice I have the following situation. In my home.jsp view I have the following link:

<a id="customArg" class="textLink" href="<c:url value="/data/custom" />">Custom</a> 

This link generate an HTTP Request towards the URL: "/data/custom"

The controller class that contain the method that handles this request have the following code:

@Controller
public class CustomArgumentController {

    @ModelAttribute
    void beforeInvokingHandlerMethod(HttpServletRequest request) {
        request.setAttribute("foo", "bar");
    }

    @RequestMapping(value="/data/custom", method=RequestMethod.GET)
    public @ResponseBody String custom(@RequestAttribute("foo") String foo) {
        return "Got 'foo' request attribute value '" + foo + "'";
    }

}

The method that handles this HTTP Request is custom(). So when the previous link is clicked, the HTTP Request is handled by the custom method.

I have some problem to understand what exactly does the @RequestAttribute annotation do. I think that, in this case, it binds the request attribute named foo to a new String foo variable. But where this attribute is taken from? Is this variable taken by Spring?

OK, my idea is that this request attribute is taken from a HttpServletRequest object. I think so because, in this class, I also have the beforeInvokingHandlerMethod() method that have a speaking name, so it seems that this method sets an attribute, that have name=foo and value=bar, inside an HttpServletRequest object, and then so the custom() method can use this value.

In fact my output is:

Got 'foo' request attribute value 'bar'

Why the beforeInvokingHandlerMethod() is called before the custom() method?

And why the beforeInvokingHandlerMethod() is annotated by @ModelAttribute annotation? What does it mean in this case?

like image 695
AndreaNobili Avatar asked Dec 15 '12 19:12

AndreaNobili


People also ask

What is the use of @ModelAttribute in Spring MVC?

@ModelAttribute is an annotation that binds a method parameter or method return value to a named model attribute, and then exposes it to a web view. In this tutorial, we'll demonstrate the usability and functionality of this annotation through a common concept, a form submitted from a company's employee.

What is the difference between @ModelAttribute and @RequestBody?

@ModelAttribute is used for binding data from request param (in key value pairs), but @RequestBody is used for binding data from whole body of the request like POST,PUT.. request types which contains other format like json, xml.

What is the difference between @RequestParam and @ModelAttribute?

@ModelAttribute and @RequestParam both interrogate the request parameters for information, but they use this information differently: @RequestParam just populates stand-alone variables (which may of course be fields in a @ModelAttribute class).

What are the difference between model ModelMap and ModelAndView in Spring MVC?

Model is an interface while ModelMap is a class. ModelAndView is just a container for both a ModelMap and a view object. It allows a controller to return both as a single value.


1 Answers

The RequestAttribute is nothing but the parameters which you have passed in the form submission. Lets understand with a sample example

Suppose I have the below form

<form action="...">
<input type=hidden name=param1 id=param1 value=test/>
</form>

Now, if I have the below controller which is mapped with the request url which is mapped with the form submission as below.

@Controller
public class CustomArgumentController {

@ModelAttribute
void beforeInvokingHandlerMethod(HttpServletRequest request) {
    request.setAttribute("foo", "bar");
}


@RequestMapping(value="/data/custom", method=RequestMethod.GET)
public @ResponseBody String custom(@RequestAttribute("param1") String param1 ) {
    // Here, I will have value of param1 as test in String object which will be mapped my Spring itself
}
like image 185
Bhavik Ambani Avatar answered Sep 24 '22 05:09

Bhavik Ambani