Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Spring MVC Basics: Key Interfaces

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

Browse > Home / Tutorials / Spring MVC Basics

Spring MVC Basics


The Spring MVC Framework offers a simple interface based infrastructure for handing web MVC architectures. In
most cases a Spring MVC application is quite testable because Spring does not require the developer to extend a
base abstract actions/controllers a la Struts.
There are many other Java-based web frameworks out there (Struts, WebWork, various JSF implementations,
Tapestry, etc.) and all have their pros and cons, but if you are already using the Spring Framework for other services,
an added benefit of using Spring MVC is that other Spring Beans can be easily injected into the web controllers. If
your services injected into your controllers are interfaces, it is then very easy to write alternate simple
implementations of those interfaces for the purpose of testing your Controllers.
Key interfaces:
 Controller — Must implement ModelAndView handleRequest(request,response) — This is the base
controller interface, comparable to the notion of a Struts Action.
 View — Must implement void render( model, request, response) This is the MVC view for a web
interaction. Implementations are responsible for rendering content, and exposing the model.
 To complete the MVC trio, note that the model is typically handled as a java.util.Map which is returned with
the view, and the values are available, for example in a JSP, using a <jsp:useBean/> where the id
corresponds to the key value in the model (Map).
Key classes:
 DispatcherServlet — the main servlet that dispatches requests to handlers. This will be typically wired into
your web.xml and you will map your URL pattern(s) to be handled with Spring MVC.
 ModelAndView — Holder for both Model and View in the web MVC framework.
 SimpleFormController — basic implementation of Controller for doing standard web form submissions;
has configurable form and success views, and an onSubmit chain for convenient overriding.

A Simple Example - Displaying a List of Widgets

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;

public void setWidgetDAO(WidgetDAO dao)


{
this.dao = dao;
}

public ModelAndView handleRequest(HttpServletRequest q,


HttpServletResponse p)
throws Exception
{
Collection widgets = dao.getWidgets();
Map model = new HashMap();
model.put("widgets", widgets);
JstlView view = new JstlView();
view.setUrl("/WEB-INF/jsp/widget_list.jsp");
return new ModelAndView("widgetList", model);
}
}
Note the view, a JstlView. In an actual application, you typically would wire up a list of views in your configuration.
Then, in your controller, you would simply pass the corresponding String for the view that the controller should
forward to. More on that later.
Given this controller, we could make a corresponding JSP page like this:
<%@ page contentType="text/html" %>

<%@ taglib prefix="c"


uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="widgets"
scope="request"
type="java.util.Collection" />
<html>
<head>
<title>Zabada Spring Examples: Widget List</title>
</head>
<body>

<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>

A More Advanced Example - Editing a Form

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 void setWidgetDAO(WidgetDAO dao)


{
this.dao = dao;
}

public WidgetEditController()
{
// need a session to hold the formBackingObject
setSessionForm(true);
// initialize the form from the formBackingObject
setBindOnNewForm(true);
}

protected Object formBackingObject(HttpServletRequest r)


throws ServletException
{
return
dao.getWidgetById(RequestUtils.getLongParameter(r, "id"));
}

/** Method updates an existing List */


protected ModelAndView onSubmit(Object command)
throws ServletException
{
Widget widget = (Widget) command;
dao.saveWidget(widget);
return new ModelAndView(getSuccessView(),
"id",
widget.getId());
}
}
Notice the key methods:
 Object formBackingObject(HttpServletRequest request) is used to set up the object to be
edited.
 ModelAndView onSubmit(Object command) is called on submission of the edit form.
Here is an example JSP to correspond with this controller:
<%@ page session="false"%>
<%@ taglib prefix="spring"
uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>

<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>

<input type="submit" value="Save"/>

</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) -->

<bean id="urlMapping" class=


"org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/widgetList">widgetListController</prop>
<prop key="/widgetEdit">widgetEditController</prop>

</props>
</property>
</bean>

<!-- CONTROLLER FOR SHOWING WIDGET LIST ON JSP -->


<bean id="widgetListController"
class="com.zabada.springrecipes.web.WidgetListController">
<!-- SET WIDGET DAO (DEFINED IN applicationContext.xml) -->

<property name="widgetDAO"><ref bean="widgetDAO"/></property>


</bean>

<!-- CONTROLLER FOR EDITING A WIDGET -->


<bean id="widgetEditController" class=
"com.zabada.springrecipes.web.WidgetEditController">
<!-- SET WIDGET DAO (DEFINED IN applicationContext.xml) -->

<property name="widgetDAO"><ref bean="widgetDAO"/></property>


<!-- SET THE VIEW FOR THE FORM -->
<property name="formView"><value>widgetEdit</value></property>
<!-- SET THE VIEW TO GO TO ON A SUCCESSFUL EDIT -->

<property name="successView">
<value>listRedirect</value>
</property>
</bean>

<!-- VIEW RESOLVER -->

<bean id="viewResolver" class=


"org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename"><value>views</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.

You might also like