What Is @Modelattribute in Spring MVC

What is @ModelAttribute in Spring MVC?

@ModelAttribute refers to a property of the Model object (the M in MVC ;)
so let's say we have a form with a form backing object that is called "Person"
Then you can have Spring MVC supply this object to a Controller method by using the @ModelAttribute annotation:

public String processForm(@ModelAttribute("person") Person person){
person.getStuff();
}

On the other hand the annotation is used to define objects which should be part of a Model.
So if you want to have a Person object referenced in the Model you can use the following method:

@ModelAttribute("person")
public Person getPerson(){
return new Person();
}

This annotated method will allow access to the Person object in your View, since it gets automatically added to the Models by Spring.

See "Using @ModelAttribute".

what is use of @ModelAttribute annotation on controller

First of all, I don't think your code is working. It would only work if you choose either of following solutions.

solution 1.

@RequestMapping("/getList")
public ModelAndView getNetAllList(@ModelAttribute("myObjVO") MYObject myObj) {

//my code here

}

<form name="myForm" th:action="@{/getList}" th:object="${myObjVO}" method="post">

solution 2:

@RequestMapping("/getList")
public ModelAndView getNetAllList( MYObject myObj) {

//my code here

}

<form name="myForm" th:action="@{/getList}" th:object="${myObject}" method="post">

If you closely look these solutions, you will have an idea when @ModelAttribute is required.

So now back to your question

You don't need @ModelAttribute just to use a bean as a parameter. ModelAttribute is used for various other purposes. Read this document and also check following two from stackoverflow answer .

What is @ModelAttribute in Spring MVC?

@ModelAttribute annotation, when to use it?

Spring MVC: please explain difference between @RequestParam and @ModelAttribute

@RequestParam just populates stand-alone variables (which may of course be fields in a @ModelAttribute class). These variables will be thrown away when the Controller is done, unless they have been fed into the model.

Don't confuse the word "model" with session. The http conversation is generally: HTTP.GET, server response, then HTTP.POST. When you have the @ModelAttribute annotation in use you are always constructing an instance of whatever you have annotated, this is what makes you think that 'feeding things to the model' might make variables stick around. This isn't correct, once the HttpServletRequest has finished those variables should no longer be a part of the browser/server conversation unless they've been saved in a session.

@ModelAttribute populates the fields of a class, which then populates an attribute of the model to be passed back to the view

Yes! To be correct, @ModelAttribute tells Spring to use its default web data binder to populate an instance of something with data from the HttpServletRequest. Choosing to pass this data back to the view is up to the programmer. When you have a method annotated with @ModelAttribute, it is being called every time code hits that servlet. When you have @ModelAttribute as one of the method's parameters, we are talking about incoming Http form data-binding.

Calling @RequestParam is a shortcut for saying request.getParameter("foo"); under the hood, Java's HttpServletRequest lets you get values from the request object by doing a key->value look up. The value returned is of type Object. This is what you would be typing a lot if you were not using Spring in your web application.

Spring then takes this abstraction a step further when you start to use @ModelAttribute. This annotation employs the concept of data-binding. The goal of data-binding is that the code in your controller won't have to call request.getParameter("foo1"), for every form element. Imagine you have a web form with 5 fields. Without data-binding the programmer has to manually retrieve, and validate each of those fields. The programmer has to make sure that the request contains the property, that the property's value exists, and that the property's value is of the type expected for each field. Using @ModelAttribute tells Spring to do this work for you.

If you annotate a method in your controller with @ModelAttribute("fooBar") FooBar fooBar An instance of FooBar will always be constructed by Spring, and supplied to your method. Where the data binding comes into play, is when this annotation is used in a Method's parameters; Spring looks at the instance of HttpServletRequest and sees if it can match the data in the request to the right property on an instance of FooBar. This is based off the java properties convention, where you have a field such as foo and public getters and setters called getFoo and setFoo. This might seem magic but if you were to break convention, your Spring data binding would stop working because it wouldn't be able to know where to bind the data from your HttpServletRequest You would still get an instance of FooBar, but the properties would not be set to any values from the request.

Spring MVC annotation @ModelAttribute

Purpose @ModelAttribute is bind param/properties from request a model object,
say @ModelAttribute("person") Person person in your method, it will bind properties from object such name, age to Person and construct a object out of it. It does not pass anything to your view, it job finishes once the request submitted. Not carried down to the view of that action.

In contrast, when you have Model model you are explicitly constructing an object with property added to its attribute. It will be carried down to your view unlike what @ModelAttribute does above

Spring MVC @ModelAttribute method

One is not better then the other. They both serve another purpose.

  • Method: If you need the model for a particular controller to be always populated with certain attributes the method level @ModelAttribute makes more sense.
  • Parameter: Use it on a parameter when you want to bind data from the request and add it to the model implicitly.

To answer your question on the better approach

I would say approach 2 is better since the data is specific to that handler.

Spring MVC: @RequestBody VS @ModelAttribute

Why is it necessary for Spring to have those two different annotations?

Two annotations are created for different application types.

- @RequestBody for restfull applications

- @ModelAttribute for web mvc application

What are their differences?

Suppose you have a java class UserData:

public class UserData {

private String firstName;
private String lastName;

//...getters and setters
}

You want to consume requests with this user data and map to your object fields.

@RequestBody is used for consuming request body and to deserialize into an Object through an HttpMessageConverter. You can provide data types that @PostMapping can accept by specifing "consumes" in this annotation.

Ref: https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestbody

Example of the POST request with user data json body:

POST /api/v1/auth HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 40
Accept: application/json, text/plain, */*
Content-Type: application/json

{"firstName":"Tyrion","lastName":"Lannister"}

You can simply annotate your method argument with annotation @RequestBody and all data will be converted in your model

@PostMapping("/user")
public void getUserData( @RequestBody UserData userData) {
// ...
}

Otherwise, you have to consume your request as string and then manually do deserialization by yourself:

ObjectMapper objectMapper = new ObjectMapper();
UserData userData = objectMapper.readValue(postBody, UserData.class)

@ModelAttribute is an enhancement for ServletRequest that saves you from having to deal with parsing and converting individual query parameters and form fields. You simply annotate your request body with this annnotation and don't need any more to do this:

String firstName= req.getParameter("firstName"); // req is HttpServletRequest
String lastName= req.getParameter("lastName"); // req is HttpServletRequest

All data will be converted by spring automatically.

Ref: https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-modelattrib-method-args

Example of the form for this request is following:

<form action="yourEndpoint" method="POST">
<input name="firstName" id="firstName" value="Tyrion">
<input name="lastName" id="lastName" value="Lannister">
<button>Submit</button>
</form>

This form will be converted by web browser to the following request that will be consumbed by spring:

POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

firstName=Tyrion&lastName=Lannister

Example of spring mvc controller:

@PostMapping("/user")
public void getUserData( @ModelAttribute UserData userData ) {
// ...
}


Related Topics



Leave a reply



Submit