Spring MVC Basics: Key Interfaces
Spring MVC Basics: Key Interfaces
Spring MVC Basics: Key Interfaces
Here is a simple example of a Controller. Here, all we are doing is making a dependency on a WidgetDAO (it can
be instantiated with setter injection) and then implementing handleRequest which simply uses the WidgetDAO
to get the collection of Widgets which we will put into a Map which will be used for the model. Remember that all
objects in the model will be available from the view. If the view is a JSP, the objects in the model can be retrieved
from using a standard useBean where the name of the bean corresponds to the corresponding key for the given
object in the map.
Here’s the code:
/**
* Simple Web Controller to show list
* of Widgets in the system on a web page
*
* @author rlambert
*/
public class WidgetListController implements Controller
{
private WidgetDAO dao;
<h2>Widget List</h2>
<table border="1">
<tr>
<th>Name</th>
<th>Size</th>
</tr>
<c:forEach var="widget" items="${widgets}">
<tr>
<td><c:out value="${widget.name}"/></td>
<td><c:out value="${widget.size}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
The Spring Framework supplies many useful Controller and View implementations that will probably solve 90% of
your needs. Here is an example of extending a Spring SimpleFormController to write a Controller to edit a
Widget.
/**
* Controller that is used to edit a Widget.
*/
public class WidgetEditController extends SimpleFormController
{
private WidgetDAO dao;
public WidgetEditController()
{
// need a session to hold the formBackingObject
setSessionForm(true);
// initialize the form from the formBackingObject
setBindOnNewForm(true);
}
<html>
<head>
<title>Edit Widget</title>
</head>
<body>
<p>
<h2>Edit Widget</h2>
<spring:bind path="command">
<font color="red">
<b><c:out value="${status.errorMessage}"/></b>
</font>
</spring:bind>
<form method="post">
<b>Name:</b>
<spring:bind path="command.name">
<font color="red">
<b><c:out value="${status.errorMessage}"/></b>
</font>
<br/><input type="text"
name="name"
value="<c:out value="${status.value}"/>" />
</spring:bind>
<p/>
<b>Size:</b>
<spring:bind path="command.size">
<font color="red">
<b><c:out value="${status.errorMessage}"/></b>
</font>
<br/><input type="text"
name="size"
value="<c:out value="${status.value}"/>" />
</spring:bind>
</form>
</body>
</html>
The tricky thing here is the <spring:bind/> tags. The command object (in this case, the Widget returned from
the controller’s formBackingObject()) is set on the session.
The <spring:bind path=”command.name”></spring:bind> binds the contents of that tag to the “name”
property of the command. So in this case, we are binding to the Widget.getName(). The status object contains
the value of the Widget.getName() property and an errorMessage contains any error for that property. JSTL
tags are used to work with these values.
Note that, without us doing any work, this example does some validation. When you run the example, try to enter a
non-integer in the size field. There is much more advanced validation that can be performed, but I won’t do any of
that here.
To get these examples to work, we just need to configure the controllers and views. First, in the web.xml, we need to
make sure that the DispatcherServlet is set up:
<!--
- Servlet that dispatches request to registered handlers
- (Controller implementations).
- Has its own application context,
- by default defined in "{servlet-name}-servlet.xml",
- i.e. "example-servlet.xml".
-
- A web app can contain any number of such servlets.
- Note that this web app has a shared root application context,
- serving as parent of all DispatcherServlet contexts.
-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
The “servlet-name” can be whatever we want. Since I named it “springmvc”, the default location for the controller and
view configuration is “/WEB-INF/springmvc-servlet.xml”. In this file we need to define the controllers, the views and
the controller url mappings. Here is an example for our two example controllers:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--URLs MAPPED TO THE SPRING CONTROLLERS (DEFINED BELOW) -->
</props>
</property>
</bean>
<property name="successView">
<value>listRedirect</value>
</property>
</bean>
</beans>
Note that any beans configured in the parent applicationContext.xml are available here, this is why we can access
the widgetDAO bean. Note the “viewResolver”. The “basename” views indicates to look for a resource bundle with
the name “views” from which to load the view mappings. This will look for locale specific bundles first and if it does
not find any, it will load the properties from “view.properties” from the classpath. Here is an example
views.properties:
widgetEdit.class=org.springframework.web.servlet.view.JstlView
widgetEdit.url=/WEB-INF/jsp/widget_edit.jsp
widgetList.class=org.springframework.web.servlet.view.JstlView
widgetList.url=/WEB-INF/jsp/widget_list.jsp
listRedirect.class=
org.springframework.web.servlet.view.RedirectView
listRedirect.url=widgetList
Summary
Spring MVC is designed with a clean interface-based design. The key interfaces to understand are View and
Controller. The trickiest part of using Spring MVC is probably wiring everything up, but once you go through this
excercise once, it is really quite simple. There is a lot more to Spring MVC. Some subjects will be detailed in later
articles. Check out the Spring JavaDocs and the resources listed below for more information.