What is @ModelAttribute
@ModelAttribute has two usage scenarios in controllers. When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form.The @ModelAttribute is a convenient annotation for exposing your objects to your JSP pages, and returning the object back to your Controllers.
You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation.
Note
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database. Such an attribute can then already be accessed through @ModelAttribute annotated handler method parameters in the chosen handler method, potentially with binding and validation applied to it.
Source: Spring 3 Reference Documentation
If you're familiar with the classin Spring of doing things, this annotation combines functionalities of a formBackingObject (or commandObject) and SimpleFormController's referenceData. However, as of Spring 3.0, these have been deprecated in favor of annotated controllers (Source: Spring 3 API SimpleFormController)
Let's start by declaring the required Spring configurations.
To enable Spring MVC we need to add it in the web.xml
web.xml
Take note of the URL pattern. When accessing any pages in our MVC application, the host name must be appended with
/kramsIn the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.
spring-servlet.xml
This XML config declares a view resolver. All references to a JSP name in the controllers will map to a corresponding JSP in the /WEB-INF/jsp location.
By convention, we must declare an applicationContext.xml
applicationContext.xml
This XML config declares three beans to activate the Spring 3 MVC programming model.
We're done with the required Spring XML configurations. We now focus on the two usage patterns of the @ModelAttribute annotation.
Pattern 1: Method Level
You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation.This means we declare a method in our controller and annotate the method with @ModelAttribute.
Source: Spring 3 Reference Documentation
We will examine this pattern by displaying a list of addresses. First let's declare our controller.
AddressController
The controller has a method named getAllAddresses() that's been annotated with @ModelAttribute. We also provide a model name addresses
The model attribute addresses is referenced in the JSP page.
addressespage.jsp
In this controller we have to mappings:
/address/list1 /address/list2Both mappings will yield the same result. However the models are retrieved in different ways.
The getAllUsingModelAttribute() method doesn't pass any model but instead relies on the @ModelAttribute for its data
Here's the actual screenshot of the JSP page from /address/list1
The getAllUsingModel() method retrieves the model by manually adding it on the Model. It also adds an extra model data named greetings
Here's the actual screenshot of the JSP page from /address/list2
They both produce the same list of addresses. So what's the difference? I don't see any except for one major difference:
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database.Using the @ModelAttribute automatically prepopulates your list. If you're doing some updates in your controller, you might still get the old list unless you specifically override the list from the @ModelAttribute.
Source: Spring 3 Reference Documentation
This is better explained when we move to the next usage pattern.
Pattern 2: Method Parameter Level
When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form.rameters in the chosen handler method, potentially with binding and validation applied to it.This means we have a method with a parameter and we annotate that parameter with a @ModelAttribute. The purpose of this pattern is to pass the data from the JSP page back to your controller. The data is automatically converted to a Java object.
Source: Spring 3 Reference Documentation
We will examine this pattern by displaying a list of persons that we can edit and update. This example will also showcase some of Spring 3's RESTful annotations.
We begin by defining our main controller.
MainController.
This controller declares two @ModelAttribute at the method level. We already know what that does. Then there's a @ModelAttribute at the method parameter level:
This basically means your JSP page is sending a model attribute named personAttribute. Your controller picks this model attribute and assign it to a Java object Person. In this way you're manipulating an object instead of HTTP request parameters.
In this controller we have three mappings:
/main - retrieve all persons /main/edit/{id} - (GET) retrieve and edit a person by his id /main/edit/{id} - (POST) save a person based on his idNotice we have two /main/edit/{id}. How does our controller know which one to call? The controller's @RequestMapping doesn't just rely on the mapping value but it also uses the method type. In our case, it's either POST or GET. The GET method is used when we retrieve a page; whereas, the POST method is used when we're submitting a form. For more info, please check the following blog from SpringSource Annotated Web MVC Controllers in Spring 2.5
Also, we're using a special identifier in the mappings. We have declared a {id} in the path, and referenced that as @PathVariable in the method parameter. This is a URI template, one of the RESTful features of Spring 3 MVC.
What is a URI template?
A URI template is a URI-like string, containing one or more variable names. When these variables are substituted for values, the template becomes a URI. For more information, see the proposed RFC.For a thorough description of this subject, please visit the blog from SpringSourceREST in Spring 3: @MVC
Source: REST in Spring 3: @MVC
Let's examine the associate JSP view for each mappings.
personspage.jsp
This is referenced by the mapping /main. There's nothing special here. This is exactly similar with our Address example earlier.
editpage.jsp
This JSP page is returned by the following controller method:
This method searches a person based on his id. If found, a model attribute is added in the Model. The name of the attribute is personAttribute. This can be any name.
To access the edit page, we need to manually type the following URL in the browser:
http://localhost:8080/spring-jsp-model-attribute/krams/main/edit/2Just make sure to change the number to match the id that you want to edit.
Here's the Edit page:
When we're done editing the person, we submit the form.
Notice we use POST to submit the data. We also use the same model attribute name. We also pass the id in the action URL.
Once the data is sent, it is picked by the controller and assigned to the saveEdit method.
I advise my readers to read the important comments within this method. To display again the list of persons we can either pass the model manually or rely on the @ModelAttribute on the Method Level. However, there's a problem if you follow the Method Level. It doesn't show the updated list. You have to refresh the browser again to see it. Why?
NoteBecause the list is populated even before it's processed by the method! As a workaround, you must pass the model manually so that you don't need to refresh the browser.
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database.
Source: Spring 3 Reference Documentation
Here's the final JSP page.
Our application is now finished. We've managed to build a simple Spring 3 MVC application that uses JSPs for the presentation layer. We've also discussed the usage patterns of the @ModelAttribute.
The best way to learn further is to try the actual application.
Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-jsp-model-attribute/
You can download the project as a Maven build. Look for the spring-jsp-model-attribute.zip in the Download sections.
You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
If you want to learn more about Spring MVC and Jasper, feel free to read my other tutorials in the Tutorials section.
Share the joy:
|
Subscribe by reader Subscribe by email Share
Thanks for the nice explanation!
ReplyDeleteThank you so much for your examples! I'll download the code and see how it works....
ReplyDeleteThanks for sharing, just one correction needed should remove these lines from pom.xml
ReplyDeletecommons-logging
commons-logging
@ronald132, thanks for pointing that out. I'm gonna check it later when I get home. Probably it's an old entry from an old pom.xml
ReplyDeleteVery helpful - thanks a lot.
ReplyDeleteThanks for clear explanation!
ReplyDeletethank you very much
ReplyDeletegreat explanation,
ReplyDeletethanks
Thanks a lot. Super :)
ReplyDeletehttp://localhost:8080/spring-jsp-classic-crud/krams/address/list1
Deletegood luck!
I am sorry that this is a stupid question, but I am stuck. Can you tell me what is the starting URL for your sample?
ReplyDeletehttp://localhost:8080/spring-jsp-model-attribute/krams/addresspage.html?
Thanks! Great tutorial, but I am stuck with this trivial roadblock.
all clear
ReplyDeletegreat explanation
ReplyDeletethanks
Awesome ! I was struggling with @ModelAtrribute usage . Now I got the hold of it.But what I am still confused about is how JSP page where is form tag is used knows it has to bind form data onto Person object. Would be great if you could explain that.
ReplyDeleteHi!
ReplyDeleteThanks for the explabation. I am currently faced with a similar modelattribute problem. Days of googling couldn't find me a solution... Maybe you could help me out?
I have a similar setup as you use in your example. Except that the curency is not a string but a currency class. I could not find a way of creating a new object via spring mvc in a form thatwould reference an existing currency. I allways end up with a new currency object embedded in the newly created object.
Could you post an exanple of such a spring mvc project.
Thanks
Dominik
@Anonymous, make sure the Currency objects that you pass are initialized and populated with values already. Then to access them on your JSP, you use dot notation, ie. currencies.currency.value or currencies.currency.name
ReplyDeleteHi krams!
ReplyDeleteThanks for your reply. My problem is that i create a new object in a form and the object references a currency. But i end up with a new currency not with a reference to an existing currency in the newly created object.
Access to the currencies works fine. They get displayed in the form as items if a select list. Do I need a form backing object and then a controller that generates my new object with the reference after the form is submitted?
Thanks again!
Dominik
@Dominik, I see the problem now. You're trying to create a new record that references an existing currency, but on your form, after submission, always creates a new currency. Usually what I do in such case is, I prepopulate the form with the currency's id. So when I submit the record, the currency's id is transmitted back to the controller. You will need to write a custom object to capture this information, meaning your domain object is now different from your data transfer object which sits on your controller. So all data you transmit will be mapped to the data transfer object. Then you map the dto to your domain object. The reason you must create a dto is because you're only passing the currency's ID not the whole object. So the property will be of type Long or Integer instead of a Currency.
ReplyDelete@Dominik, instead of using Spring's form support, I suggest you use jQuery or similar and work on JSON objects instead. Another advantage in this approach is you don't need to use the @ModelAttribute anymore. You use standard HTML form tags as well.
ReplyDeleteHi Krams, Could you explain how to pass the entire object from jsp to spring controller? Example:
ReplyDeletevar="deleteUrl" value="/main/persons/delete.htm?id=person.id"
href="${deleteUrl}">Delete
And the controller is:
@RequestMapping(value = "/persons/delete", method = RequestMethod.GET)
public String delete(@ModelAttribute("id") PersonsID id, Model model) {
id.getId();
id.getInf();
return "deleted_";
}
Thanks in advance, have a nice day!!.
Vulcano
Great article !
ReplyDeleteThank you for your work
I am really new to Spring3.Amazing source code. really very helpful for me. Appreciate your help in uploading and explaining.
ReplyDeleteAmazing stuff and explanation.
ReplyDeleteHow do you get errors back to the page if your not using a BindingResult?
ReplyDeleteNice explanation! Very well done.
ReplyDeleteI have one doubt..What are the cases in which model attribute values are automatically pushed into the handler methods.??and when we need to manually add into our model.??Pls help..Am in bit confusion..
ReplyDeleteCan someone explain me how to setup project in eclipse propply
ReplyDeleteThanks for the great tutorial, I'm trying to use it on a Weblogic 10.3.5 instance but I got a java exception about ELResolver unable to handle null base object. Can somebody help me?
ReplyDeleteStill fairly new to Spring, but to solve the updated modelattribute after POST issue, couldn't/shouldn't you use a redirect to the same page if the addition of the object was successful? In doing so wouldn't the modelattribute update and also the add form would be cleared to add another person?
ReplyDeleteThanks for the explanation
ReplyDeleteAfter update, method saveEdit should redirect to show person list instead of forwarding. This will avoid duplicate submit (Edit multiple times)
ReplyDeleteGreat!!
ReplyDeleteThanks Krams :)
Thanks.
ReplyDeleteAlthough, I had to add an exclude of commons-logging for spring-web (in pom.xml) in order to make it work. Commons-logging is only excluded for spring-core for some reason.
Hi Krams,
ReplyDeleteThanks for your post. I have a quick question about css file. I have a project, which is using css file for styles and background images, after providing static content path in my spring servlet like:
I am able to access all images and static files in jsp using like <img src="”, but there is some background images path defined in my css. Can you please advise how to give a path in css about images since css file doesn’t understand spring tags.
Thank you very much your help.
Thanks,
Srini
I suggest you looked at some of my latest tutorials on how I've exposed resources.
DeleteHi Krams,
ReplyDeletethank you for you tutorial. I downloaded the zip file, xtracted it and imported it into STS. It is compiling, but a load of http://localhost:8080/spring-jsp-classic-crud/krams/address/list1 gives me a white page.
Any hint?
Thank you
Great tutorial!
ReplyDeleteTHANKS!
gr8
ReplyDeleteThank you for this nice and well explained Tutorial.
ReplyDeleteOne of the simple and easy example to understand the concept quickly and clearly
ReplyDeleteGreat Work!!!
ReplyDeleteHi Krams,i am going to define my prob in step wise..
ReplyDelete1) in my spring proj , i am using login and logout .
2) when i click logout button then i get successful logout but when i
click browser back button is still working and i can see the last
page why?
How can i dowload your project ?
ReplyDeleteit say "The requested URL /files/spring-jsp-model-attribute.zip was not found on this server."
I have read your blog its very attractive and impressive. I like it your blog.
ReplyDeleteSpring online training Spring online training Spring Hibernate online training Spring Hibernate online training Java online training
spring training in chennai spring hibernate training in chennai
Thanks a lot! You made a new blog entry to answer my question; I really appreciate your time and effort.
ReplyDeleteCore java training in chennai |
best java institute in chennai
Nice looking sites and great work. Pretty nice information. it has a better understanding. thanks for spending time on it.
ReplyDeleteBest BCA Colleges in Noida
Great Article… I love to read your articles because your writing style is too good,
ReplyDeleteits is very very helpful for all of us and I never get bored while reading your article because,
they are becomes a more and more interesting from the starting lines until the end.
Java training in Chennai
Java training in Bangalore
Java online training
Java training in Pune
Big data service providers should understand the need of Data, and they should work to build more appropriate services to meet the requirements of their clients.
ReplyDeleteEffective blog with a lot of information. I just Shared you the link below for Courses .They really provide good level of training and Placement,I just Had Spring Classes in this institute , Just Check This Link You can get it more information about the Spring course.
ReplyDeleteJava training in chennai | Java training in annanagar | Java training in omr | Java training in porur | Java training in tambaram | Java training in velachery
thanks for sharing this blog buy marijuana online and pills, Buy clonazepam powder online
ReplyDeleteBuy clonazepam powder online
Buy 2-nmc online
Buy adderall online
Buy actavis-promethazine-codeine online
Buy marijuana online online
Buy Wiz Khalifa OG online
Buy Green Crack online
Buy Girl Scout Cookies online
Buy AK-47 online
Buy Moon Rocks online
This is my blog. Click here.
ReplyDeletemakeuplifeyou.wixsite.com
byou59485.wixsite
software testing company in India
ReplyDeletesoftware testing company in Hyderabad
Interesting and informative bog.
Thanks for sharing such an amazing blog with us.
Nowadays, id verification service is higher in need. There are numerous id verification methods that anybody can receive on a professional site termed Trust Swiftly, and an agency can use the methods to secure their own web business ideally. By visiting this excellent https://www.trustswiftly.com internet site, you can obtain details of id verification service.
ReplyDeleteinformative blog.thank you
ReplyDeletebest-angular-training in chennai |
i found your this call despite the fact that searching for a few related reference concerning blog search...Its a nice publicize..store posting and update the mention. Nord VPN Crack
ReplyDeleteGlass Door Repairman
ReplyDeleteTermite Exterminator in Liberal KS
Investor Friendly Contracting KCMO
Licensed Contracting Group Near Me
Buy My Home Fast
This comment has been removed by the author.
ReplyDeleteThank you for sharing your awesome and valuable article this is the best blog for the students they can also learn.
ReplyDeleteinstagram takipçi satın al
ReplyDeletecasino siteleri
KFU
kütahya
ReplyDeletesarıyer
serdivan
siirt
van
2UJİ