Use the Spring Web MVC Web Framework
One of the many things Spring provides is a framework for web applications. This “Spring Web MVC” framework provides a lot of common features required in most web applications. This helps simplify the programming of web applications using Spring Web MVC so that the developers can focus on what the application is supposed to do instead of creating a framework to support web applications.
In this lab you will use some of these features of Spring Web MVC. This will be a simple application that manages “Purchase” data but will be enough to demonstrate the main features of the Spring Web MVC framework.
Lab Setup
- Import the projects in the ‘<LABFILES>Spring‑MVCSpring‑MVC‑Starter.zip‘ file as described in the ‘Common Lab Preparation Steps’ at the ‘Lab Setup’ part.
- Open the Spring perspective.
Configure Database
This project will use a database to store the data edited by the web application. The steps to configure the database will be done first before any code is altered.
- Start the database following the steps in the ‘Common Lab Preparation Steps‘ at the ‘Start Derby Database‘ part.
- Follow the steps in the ‘Initialize Derby Database‘ section of the ‘Common Lab Preparation Steps‘ using the ‘db.txt’ database script from the ‘<LABFILES>Spring‑MVC‘ folder.
- Follow the steps in the ‘Configure JBoss Derby DataSource‘ section of the ‘Common Lab Preparation Steps‘ using the ‘..-ds.xml’ file from the ‘<LABFILES>Spring‑MVC‘ folder.
Add Spring MVC Dependencies
Since Spring can be used without the Spring MVC framework it is provided in a separate module from the “core” parts of Spring. There is only a little bit you need to add to make the Spring MVC framework available though.
- Open the pom.xml file from the root of the ‘Spring-MVC‘ project.
- Switch to the source of the pom.xml by selecting the ‘pom.xml‘ tab along the bottom of the editor. You might need to look for some tabs that are hidden on the far right side and expand those to select the proper view.
- Near the bottom of the file find the section that is commented out (<!– .. –>) that has the dependencies for Spring Web MVC support. Remove the comment tags from before and after this section so the Spring Web MVC modules are an active dependency.<dependency><groupId>org.springframework</groupId>
<artifactId>org.springframework.web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web.servlet</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
- Save the file and be sure there are no red errors in the margin for the file. These will occur if you don’t remove the comments properly.
- Expand the ‘Maven Dependencies‘ for the project in the ‘Package Explorer’ view and make sure you see the Spring web modules listed. There will be other JARs also imported.
- Collapse the dependencies again.
Modify Basic Spring MVC Configuration
The first step to do with this project is to modify the application to configure some basic Spring MVC elements. This will include the Spring MVC “Dispatch Servlet”, a Spring MVC “View Handler” and a simple “View controller” for the index page of the application.
- Open the ‘WebContent/WEB-INF/web.xml‘ file.
- Switch to the ‘Source‘ tab of the editor.
- Notice there is an existing Servlet definition for the Spring MVC “DispatcherServlet”. This configuration is fairly complex so it was provided for you to simplify things. Of particular importance notice there is an <init-param> for the servlet which configures which Spring configuration files to load. There is also the ‘ContextLoaderListener’ which is required for some of the Spring MVC tags we will use later
- Notice there is an existing Servlet definition for the Spring MVC “DispatcherServlet”. This configuration is fairly complex so it was provided for you to simplify things. Of particular importance notice there is an <init-param> for the servlet which configures which Spring configuration files to load. There is also the ‘ContextLoaderListener’ which is required for some of the Spring MVC tags we will use later.<servlet><servlet-name>SpringDispatch</servlet-name><servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<description></description>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-jpa.xml,
/WEB-INF/spring-service.xml,
/WEB-INF/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringDispatch</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-jpa.xml,
/WEB-INF/spring-service.xml,
/WEB-INF/spring-mvc.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
- Close the file and make sure you didn’t make any changes.
- Open the ‘WebContent/WEB-INF/spring-mvc.xml‘ file.
- Switch to the ‘Source‘ tab of the editor.
- Find the comment about the MVC annotation configuration and add the following element. Make sure it is not within any other element except the root <beans> element. You can also find code to copy/paste from in the<LABFILES>Spring‑MVCSolutionspring-mvc.xml file.<!– Need mvc annotation configuration ->
<mvc:annotation-driven />Note: This will enable configuring Spring MVC “Controllers” with annotations which will be done later. - Notice that there is already a <context:component-scan> element. This will look for any classes annotated with Spring component declaration annotations. In particular this will find a Spring MVC @Controller component.<context:component-scan base-package=”com.webage.web”></context:component-scan>
- Find the comment about the “View Resolver” and add the following Spring bean definition. Be careful as the class name is long and the configuration splits over several lines.
<!– Need View Resolver –>
<bean id=”viewResolver” class=“org.springframework.web.servlet.view.InternalResourceViewResolver”><property name=”prefix”>
<value>/</value>
</property>
<property name=”suffix”>
<value>.jsp</value>
</property>
</bean>
Note: The name ‘viewResolver’ of this bean is important so that Spring MVC will use it to locate how to map JSP files to the “views” returned by the Spring MVC controller methods later.
- Finally, find the comment that mentions a ‘view-controller’ for the index page. Add the following syntax to configure this.<!– Need mvc:view-controller for index page –><mvc:view-controller path=”/” view-name=”index” />Note: This will map any request for the root of the web application to the “index” view. This will end up being ‘index.jsp’ based on the view resolver configuration. This is important since the web.xml file didn’t have any “welcome pages” that would have mapped this kind of request outside of Spring.
- Save the file and make sure there are no errors.
Test Spring MVC Configuration
Before going too much further it will be good to test the current state of the project. Even though there is currently no other functionality you can test the request that should go to the ‘index.jsp’ file. This would test some of the configuration you just added to the ‘spring‑mvc.xml’ file.
- In the Servers view, right click on JBoss 5.1 server and select Start if the server is not already running. Wait for the server to start completely.
- Right click the server and select Add and Remove…, then remove all other applications that might be on the server. Select Spring-MVC and click Add>.
- Click Finish. The project will be published in the server.
- Open a web browser to:
http://localhost:8080/Spring-MVC - Verify that you get the home page of the application. None of the links will work but seeing the page proves the Spring configuration was working.
- Close down any browser.
- Leave your server running.
Implement Browse Function
The first function that will be easiest to implement is the ability to browse the content of the database. The underlying database function is already implemented and we just need to add the Spring MVC web functionality in front of it.
- Open the ‘WebContent/index.jsp‘ file.
- Find the comment at the top of the file for the Spring taglib and add the following syntax. You can also find code to copy/paste from in the
<LABFILES>Spring‑MVCSolutionindex.jsp file.<!– Need taglib for Spring tags –><%@ taglib prefix=”s” uri=”http://www.springframework.org/tags”%>
<html> - Save the file and make sure there are no errors with the tag library declaration.
- Further down in the file find the first comment about a URL for the ‘Add Purchase’ link. Modify the ‘href’ attribute of the link to include the Spring <s:url> tag shown in bold below. Be careful with the syntax as there are several double quotes and tag brackets.<!– Need URL for link –><a href=”<s:url value=”/add” />“>Add Purchase</a><br/>
Note: Sometimes in the JSP editor you will get mysterious red underlining pointing out an error that isn’t there. If this happens, close all files, right click the JSP in question and select Validate, click OK on the box that comes up with the validation results, and then reopen the file. If the red underlining doesn’t disappear when you do this double check your syntax and then ask your instructor.
- Find the second comment about needing a URL for the link for the ‘Browse Purchases’ link. Modify the ‘href’ attribute of the link to include the Spring <s:url> tag shown in bold below. Be careful with the syntax as there are several double quotes and tag brackets.<br/><!– Need URL for link –><a href=”<s:url value=”/browse” />“>Browse Purchases</a>
- Save the file and make sure there are no errors.
- In the Package Explorer view, expand the following folders:
Spring-MVC -> src -> com.webage.web - Open the PurchaseController.java file in the com.webage.web package by double clicking it. Notice that right now it is empty except for the Spring MVC @Controller annotation on the class and the @Autowired injection of a ‘PurchaseService’ component.
- Add the following new ‘browsePurchases’ method to the body of the class. The @RequestMapping annotation links this method to the ‘/browse’ URL you used in the index.jsp page.
@RequestMapping(“/browse”)
public ModelAndView browsePurchases(){
List<Purchase> list =purchaseService.findAllPurchases();
return new ModelAndView(“browsePurchases”,“purchaseList”, list);
}
Note: Also important is the ModelAndView object returned from the method. This will display the ‘browsePurchases’ view and make the list of purchases available as the ‘purchaseList’ variable in the view. You will see this used in the ‘browsePurchases.jsp’ file next.
- From the menu, select Source → Organize Imports selecting java.util.List and clicking the Finish button when prompted.
- Save the file and make sure there are no errors.
- Open the ‘WebContent/browsePurchases.jsp‘ file.
- Find the comment at the top of the file for the Spring taglib and add the following syntax. You can also find code to copy/paste from in the
<LABFILES>Spring‑MVCSolutionbrowsePurchases-BROWSE.jsp file.
<!– Need taglib for Spring tags –>
<%@ taglib prefix=”s” uri=”http://www.springframework.org/tags”%>
<html> - Save the file and make sure there are no errors with the tag library declaration.
- Find the <c:forEach> tag in the file about 2/3 of the way down. Notice that it will iterate over the ‘purchaseList’ that was made available by the controller. Each individual item will be available as the ‘purchase’ variable.<c:forEach items=”${purchaseList}” var=”purchase”><tr><!– Add Edit link –><td>Edit</td>
<!– Other purchase details –>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</c:forEach>
- Within the four columns that are currently empty add the following syntax for various expressions and a <fmt:formatDate> tag.<!– Other purchase details –><td>${purchase.id}</td><td>${purchase.customerName}</td>
<td><fmt:formatDate value=”${purchase.purchaseDate}”type=”date” pattern=”MMM d, yyyy”/></td>
<td>${purchase.product}</td>
- Further down in the file find the comment about a URL for the ‘Back to Main Menu’ link. Modify the ‘href’ attribute of the link to include the Spring <s:url> tag shown in bold below. Be careful with the syntax as there are several double quotes and tag brackets. The value is also meant to be just a single slash as this will link to the root of the application.<!– Need URL for index page –><a href=’<s:url value=”/” />‘>Back to Main Menu</a><jsp:include page=”footer.jsp” />
- Save the file and make sure there are no errors.
Test Browse Function
We should be able to test the browse feature before implementing any other feature.
- Make sure your JBoss server is started in the Servers view and start it if it is not.
- In the Servers view, expand the JBoss 5.1 server, right click the Spring‑MVC application and select Full Publish.
- Open a web browser to: http://localhost:8080/Spring-MVC
- Click on the ‘Browse Purchases‘ link and be sure you get the list of the three purchases currently in the database.
- Click on the ‘Back to Main Menu‘ link and make sure the home page is displayed.
- Close down any browser.
- Leave your server running.
Implement Add Function
The next function that can be implemented will be adding new data. We will reuse the page to supply Purchase data in the add and edit functions so the add function will need to supply a new Purchase object that can be linked by Spring MVC to the various elements of the form. We will also need a ‘save’ function to store the data.
- Return to the PurchaseController.java file in the com.webage.web package and open it again if you had closed it.
- Add the following new ‘addPurchase’ method to the body of the class. This will initialize a new Purchase object that will be bound to the various fields of the form on the ‘addEditPurchase’ page. Notice in this case, after adding the new Purchase object into the “Model” we just return a String for the name of the next view. You can also find code to copy/paste from in the
<LABFILES>Spring‑MVCSolutionPurchaseController‑ADD.java file.
@RequestMapping(“/add”)
public String addPurchase(Model model) {
model.addAttribute(“purchase”, new Purchase());
return “addEditPurchase”;
} - Select Source → Organize Imports selecting org.springframework.ui.Model and clicking the Finish button when prompted.
- Save the file and make sure there are no errors but leave it open.
- Open the ‘WebContent/addEditPurchase.jsp‘ file.
- Find the comment at the top of the file for the Spring taglib and add the following syntax. You can also find code to copy/paste from in the
<LABFILES>Spring‑MVCSolutionaddEditPurchase-ADD.jsp file.<!– Need taglib for Spring tags –><%@ taglib prefix=”s” url=”http://www.springframework.org/tags%>
<%@ taglib prefix=”form”url=”http://www.springframework.org/tags/form” %>
<html>
Note: You are adding the Spring form tags that are part of Spring MVC in addition to the core Spring tags. These form tags will be used as part of the code of the form to be submitted.
- Save the file and make sure there are no errors with the tag library declarations.
- Find the comment that mentions the “save URL” and add the following <s:url> tag. This will declare the URL the form will be submitted to to save the Purchase as a variable so it can be used in the form action.<!– Save URL here –><s:url var=”saveURL” value=”/save” />
<!– Spring form tag around table –> - Immediately after the comment that mentions the “Spring from tag around table” find the starting and ending <table> tags. Place the starting and ending <form:form> tags around the table making sure all the tags are properly nested and balanced. Note that in the code below the body of the table has been left out to see the start and end tags easily.<!– Spring form tag around table –><form:form action=”${saveURL}” commandName=”purchase”>
<table><tr>…</tr></table>
</form:form>
Note: The ‘commandName’ uses the same name as the name of the Model attribute that was added in the controller. This will find the object and link it to the form.Also notice the ‘saveURL’ variable is used for the action of the form.
- In the first three rows of the table add the <form:input> tags shown in bold below.<tr><td>Customer Name</td><td><form:input path=”customerName” size=”40″/></td></tr>
<tr>
<td>Purchase Date</td>
<td><form:input path=”purchaseDate” size=”20″ />Use format: MMM d, yyyy</td>
</tr>
<tr>
<td>Product</td>
<td><form:input path=”product” size=”30″ /></td>
</tr>
Note: The ‘path’ attribute of the <form:input> tag links to a property of the Java object used as the “command” of the form.
- In the last row, modify the ‘href’ attribute of the link to include the Spring <s:url> tag shown in bold below. Be careful with the syntax as there are several double quotes and tag brackets.<tr><td><input type=”submit” value=”Save”></td><!– Add URL for cancel –><td><a href=’<s:url value=”/” />‘>Cancel</a>
</td>
</tr>
- Save the ‘addEditPurchase.jsp’ file and be sure there are no errors.
- Return to the PurchaseController.java file in the com.webage.web package and open it again if you had closed it.
- Add the following new ‘savePurchase’ method to the body of the class. Notice the parameter of the method is a Purchase object. Spring MVC is able to initialize this object based on the fact the form had been linked to properties of the object. Also the view is a redirect request for the ‘browse’ view which is already mapped by the ‘browsePurchases’ method of the controller.
@RequestMapping(“/save”)
public String savePurchase(Purchase purchase) {
purchaseService.savePurchase(purchase);
return “redirect:browse”;
}
- Add the following new ‘initBinder’ method to the body of the class. This will register a specific date format that will be used as the default for any Java object used in the display of a Spring MVC view.
@InitBinder
public void initBinder(WebDataBinder binder){String dateFmtStr = “MMM d, yyyy”;
DateFormat dateFormat =new SimpleDateFormat(dateFmtStr);
dateFormat.setLenient(false);
CustomDateEditor editor =new CustomDateEditor(dateFormat, true);
binder.registerCustomEditor(Date.class, editor);
}
- Select Source → Organize Imports selecting java.util.Date and clicking the Finish button when prompted.
- Save the file.
- Close all open files and make sure there are no errors in the project.
Test Add Function
Even though editing existing data is still left we will test the
function to add new data.
- Make sure your JBoss server is started in the Servers view and start it if it is not.
- In the Servers view, expand the JBoss 5.1 server, right click the Spring‑MVC application and select Full Publish.
- Open a web browser to: http://localhost:8080/Spring-MVC
- Click on the ‘Add Purchase‘ link to bring up the form.
- Click the Cancel link at the bottom and make sure you are sent back to the main page.
- Click on the ‘Add Purchase‘ link again to bring up the form.
- Fill in some data for the form, making sure to use the correct format for the date.
- Click the ‘Save‘ button to submit the form. Make sure you see the list of all Purchases with the new record in the database.
- Close down any browser.
- Leave your server running.
Implement Edit Function
The last thing to be able to do is to edit existing data. We will need
to make an important modification to the form to preserve the ID of the
record being edited.
- Return to the PurchaseController.java file in the com.webage.web package and open it again.
- Add the following new ‘editPurchase’ method to the body of the class. Notice this will take the ‘purchaseId’ property from the path of the request and pass it in as a method parameter. This will be used to lookup the existing record and store the Purchase object as a Model attribute. You can also find code to copy/paste from in the <LABFILES>Spring‑MVCSolutionPurchaseController‑EDIT.java file.
@RequestMapping(“/edit/{purchaseId}”)
public String editPurchase(@PathVariable int purchaseId, Model model){Purchase toEdit =purchaseService.findPurchaseById(purchaseId);
model.addAttribute(“purchase”, toEdit);
return “addEditPurchase”;
}
- Select Source → Organize Imports.
- Save the file and make sure there are no errors.
- Open the ‘WebContent/browsePurchases.jsp‘ file.
- Find the comment about adding the ‘Edit’ link and add the following link around the text ‘Edit’ which is already there. Make sure to add the ending </a> tag after the ‘Edit’ text. Notice this is a regular HTML <a> anchor tag and only needs to add the purchase ID to the link. You can also find code to copy/paste from in the <LABFILES>Spring‑MVCSolutionbrowsePurchases-EDIT.jsp file.<!– Add Edit link –><td><a href=”edit/${purchase.id}”>Edit</a></td><!– Other purchase details –>
- Save the file and make sure there are no errors.
- Open the ‘WebContent/addEditPurchase.jsp‘ file.
- Find the start of the <form:form> tag and add the following <form:hidden> tag, making sure it is inside the body of the form. This will preserve the ID of the Purchase object if being edited. You can also find code to copy/paste from in the <LABFILES>Spring‑MVCSolutionaddEditPurchase-EDIT.jsp file.<!– Spring form tag around table –><form:form action=”${saveURL}” commandName=”purchase”><form:hidden path=”id” />
<table>
Note: This was not needed when adding new data because the JPA code indicates the ID is generated by the database so we did not need a parameter for the ID. If you do not add it here you will not be able to edit data because the application will always view the Purchase object as a new object. - Save the file and make sure there are no errors.
Test Edit Function
Finally we can test the last function implemented in the application.
- Make sure your JBoss server is started in the Servers view and start it if it is not.
- In the Servers view, expand the JBoss 5.1 server, right click the Spring‑MVC application and select Full Publish.
- Open a web browser to: http://localhost:8080/Spring-MVC
- Click on the ‘Browse Purchases‘ link. You should see the same list but this time there should be a link for the ‘Edit’ text in the first column of every row of the table.
- Click on the ‘Edit‘ link next to one of the Purchases.
- Make a change to the data. Make sure it is a change you will recognize from the list. Also, if you change the date, make sure to use the correct format.
- Click the ‘Save‘ button to submit the form. Make sure you see the change in the data you modified.
- Close down any browser.
- Close any open files.
Lab Cleanup
- Undeploy and close the Spring-MVC project as described in the ‘Common Lab Preparation Steps’ at the ‘Lab Cleanup’ part.
- Stop the database following the steps in the ‘Common Lab Preparation Steps‘ at the ‘Stop Derby Database‘ part.
Review
Spring MVC has many useful features that simplify web application programming. Spring MVC can do things like register URLs that are requested with Controller methods or view pages and bind the properties of a Java object to the fields on a form. Spring MVC also provides several JSP tags that are useful in the pages of the application.
Although this lab only showed a brief part of what is possible with Spring MVC you got a sense for the “Model, View, Controller” framework that is what makes up Spring MVC.
Related Training
J2EE Application Development with Spring and Hibernate Using RAD 7.0
Spring 3 Fundamentals Using Eclipse and WebSphere
Developing J2EE Applications Using Spring 2.0 and Eclipse
Core Spring 3 on JBoss Using SpringSource Tool Suite
Developing J2EE Applications Using Spring 2.5 and Rational Application Developer (RAD) v7.0