The document describes the Spring MVC request lifecycle and how requests are handled in Spring MVC. It discusses how the DispatcherServlet receives requests and uses handler mappings to determine which controller should handle each request. It then describes how controllers process requests, returning a ModelAndView which is used to render the view. It also provides details on configuring controllers, view resolvers, and handler mappings, as well as examples of different types of controllers like command, form, and multi-action controllers.
2. Life Cycle of Spring MVC Request
All the requests are passed through a single front
controller servlet called the DispatcherServlet.
The DispatcherServlet’s job is to send the request on to
a Spring MVC controller, were an application may have
several controllers.
The DispatcherServlet consults one or more handler
mappings which determine appropriate controller
based on the request URL.
DispatcherServlet then sends the request on its to the
chosen controller.
4. Life Cycle of Spring MVC Request
At the controller, the request’s payload is dropped off
and the information is processed.
The logic in the controller comes up with the Result
information after processing referred as model.
At last the controller packages up the model data and
the name of a view for display into a ModelAndView
object.
The ModelAndView object contains model data and
the logical name to be used to lookup for actual html
view.
The controller sends the request and the
ModelAndView object back to the DispatcherServlet.
5. Life Cycle of Spring MVC Request
The DispatcherServlet asks a View Resolver to help
find the actual JSP View.
The DispatcherServlet then delivers the model data to
the View implementation thus completing the
request’s job.
6. DispatcherServlet Configuration
The DispatcherServlet must be configured in the web
application’s web.xml file.
<servlet>
<servlet-name>roadrantz</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Adding <servlet-mapping> to web.xml enables
DispatcherServlet to indiacte the URL’s it will be handling.
<servlet-mapping>
<servlet-name>roadrantz</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
7. DispatcherServlet Configuration
By default, when DispatcherServlet is loaded, it loads
the Spring application context from an XML file whose
name is based on the name of the servlet <servlet-
name>.
Also application context can be split across multiple
XML files based on various application layers.
It help keeping the maintenance easier and allowing
files to be focused on a single layer of the application.
8. Context Loader Configuration
A context loader is added to web.xml as it loads
context configuration files in addition to the one that
DispatcherServlet loads.
Context loader is a servlet listener called
ContextLoaderListener.
<listener>
<listener-class>org.springframework.
web.context.ContextLoaderListener</listener-class>
</listener>
9. Context Loader Configuration
Context Loader configures the location of the Spring
configuration file(s) to load which is “/WEB-
INF/applicationContext.xml” by default.
The contextConfigLocation parameter in the servlet
context specifies one or more Spring configuration files for
the context loader to load.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/roadrantz-service.xml
/WEB-INF/roadrantz-data.xml
/WEB-INF/roadrantz-security.xml
</param-value>
</context-param>
10. Steps to Build Homepage in Spring MVC
Write the controller class that performs the logic
behind the homepage. The logic involves using a
RantService to retrieve the list of recent rants.
Configure the controller in the DispatcherServlet’s
context configuration file (roadrantz-servlet.xml).
Configure a view resolver to tie the controller to the
JSP.
Write the JSP that will render the homepage to the
user.
11. Building the controller
public class HomePageController extends AbstractController {
public HomePageController() {}
protected ModelAndView handleRequestInternal(
HttpServletRequest request, HttpServletResponse response)
throws Exception {
List recentRants = rantService.getRecentRants();
return new ModelAndView("home", "rants", recentRants);
}
private RantService rantService;
public void setRantService(RantService rantService) {
this.rantService = rantService;
}
}
12. ModelAndView
A ModelAndView object fully encapsulates the view and
model data that is to be displayed by the view.
The ModelAndView object is constructed as follows:
new ModelAndView("home", "rants", recentRants);
The first parameter of the ModelAndView constructor is
the logical name of a view component which is used to
display the output from the controller.
A view resolver will use the view name to look up the actual
View object.
The next two parameters which acts as name-value pair
represent the model object that will be passed to the view.
13. Configuring the Controller
<bean name="/home.htm"
class="com.roadrantz.mvc.HomePageController">
<property name="rantService" ref="rantService" />
</bean>
Here, the rantService property is injected with an
implementation of the RantService interface.
Also bean name is specified instead of bean id as the URL
pattern is not valid for bean id attribute.
The name attribute serves a double duty as both the name
of the bean and a URL pattern for requests that should be
handled by the controller. It can be avoided by configuring
a handlermapping bean.
The default handler mapping used by DispatcherServlet is
BeanNameUrlHandlerMapping, which uses the base name
as the URL pattern.
14. View Resolver Declaration
A view resolver’s job is to take the view name returned in the
ModelAndView and map it to a view (i.e. a JSP file that renders
the webpage).
InternalResourceViewResolver prefixes the view name returned
in the ModelAndView with the value of its prefix property and
suffixes it with the value from its suffix property.
<bean id="viewResolver“ class="org.springframework.web.
servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
16. Summary of Spring MVC Process
DispatcherServlet receives a request whose URL pattern is
/home.htm.
DispatcherServlet consults BeanNameUrlHandlerMapping to
find a controller whose bean name is /home.htm; it finds the
HomePageController bean.
DispatcherServlet dispatches the request to
HomePageController for processing.
HomePageController returns a ModelAndView object with a
logical view name of home and a list of rants in a property called
rants
DispatcherServlet consults its view resolver (configured as
InternalResourceViewResolver) to find a view whose logical
name is home. InternalResourceViewResolver returns the path
to /WEB-INF/jsp/home.jsp.
DispatcherServlet forwards the request to the JSP at /WEB-
INF/jsp/home.jsp to render the homepage to the user
17. Mapping requests to controllers
Handler mappings help DispatcherServlet to figure out which
controller the request should be sent to.
Handler mappings typically map a specific controller bean to a
URL pattern.
All of Spring MVC’s handler mappings implement the
org.springframework.web.servlet.HandlerMapping interface.
All of the Spring handler mapping classes implement Spring’s
Ordered interface.
Hence multiple handler mappings can be declared in the
application and set their order properties to indicate which has
precedence with relation to the others.
The lower the value of the order property, the higher the priority.
<bean id="beanNameUrlMapping“
class="org.springframework.web.servlet.handler.BeanNameUrlH
andlerMapping">
<property name="order"><value>1</value></property>
</bean>
18. Spring MVC Handler mappings
Handler mapping How it maps requests to controllers
BeanNameUrlHandlerMapping Maps controllers to URLs that are based
on the controllers’ bean name.
SimpleUrlHandlerMapping Maps controllers to URLs using a
property collection defined in the Spring
application context.
ControllerClassNameHandlerMapping Maps controllers to URLs by using the
controller’s class name as the basis for the
URL.
CommonsPathMapHandlerMapping Maps controllers to URLs using source-
level metadata placed in the controller
code. The metadata is defined using
Jakarta Commons Attributes
(http://jakarta.apache.org/commons/
attributes).
19. SimpleUrlHandlerMapping
It allows to map URL patterns directly to controllers
without having to name the beans in a special way.
<bean id="simpleUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/home.htm">homePageController</prop>
<prop key="/rantsForVehicle.htm“>rantsForVehicleController</prop>
<prop key="/rantsForVehicle.rss“>rantsForVehicleControllerRss</prop>
<prop key="/rantsForDay.htm">rantsForDayController</prop>
<prop key="/login.htm">loginController</prop>
<prop key="/register.htm">registerMotoristController</prop>
<prop key="/addRant.htm">addRantController</prop>
</props>
</property>
</bean>
20. SimpleUrlHandlerMapping
SimpleUrlHandlerMapping’s mappings property is
wired with a java.util.Properties using <props>.
The key attribute of each <prop> element is a URL
pattern.
All the URL patterns are relative to DispatcherServlet’s
<servlet-mapping>.
The value of each <prop> is the bean name of a
controller that will handle requests to the URL
pattern.
21. ControllerClassNameHandlerMapping
It is used when mapping the controllers to URL
patterns is quite similar to the class names of the
controllers.
<bean id="urlMapping”
class="org.springframework.web.servlet.mvc.
ControllerClassNameHandlerMapping"/>
It enables the DispatcherServlet to map URL patterns
to the controllers following a simple convention.
Spring automatically maps the controllers to URL
patterns that are based on the controller’s class name.
22. Metadata Map Controllers
The CommonsPathMapHandlerMapping considers
source-level metadata placed in a controller’s source
code to determine the URL mapping.
The metadata is expected to be an
org.springframework.web.servlet.handler.commonsatt
ributes.PathMap attribute compiled into the controller
using the Jakarta Commons Attributes compiler.
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.meta
data.CommonsPathMapHandlerMapping"/>
23. Metadata Map Controllers
Each of the Controllers is tagged with a PathMap attribute to
declare the URL pattern for the controller.
For example, to map HomePageController to /home.htm, tag
HomePageController as follows:
/**
* @@org.springframework.web.servlet.handler.
commonsattributes.PathMap("/home.htm")
*/
public class HomePageController
extends AbstractController { …..
}
The build need to be set up to include the Commons Attributes
compiler so that the attributes will be compiled into the
application code.
24. Handling requests with controllers
The Controller interface is at the top of the controller
hierarchy.
Any class implementing Controller interface can be
used to handle requests through the Spring MVC.
25.
26. Spring MVC Controller Classes
Controller
type
Classes Useful when…
View ParameterizableViewController
UrlFilenameViewController
Controller only needs to display
a static view—no processing or
data retrieval is needed
Simple Controller (interface)
AbstractController
Controller is extremely simple,
requiring little more
functionality than is afforded by
basic Java servlets.
Throwaway ThrowawayController A simple way to handle requests
as commands (in a manner
similar to WebWork
Actions).
Multiaction MultiActionController Application has several
actions that perform similar or
related logic.
27. Spring MVC Controller Classes
Controller
type
Classes Useful when…
Command BaseCommandController
AbstractCommandController
Controller will accept one or
more parameters from the
request and bind them to an
object. Also capable of
performing parameter
validation.
Form AbstractFormController
SimpleFormController
To display an entry form to the
user and also process the data
entered into the form
Wizard AbstractWizardFormController To walk the user through a
complex, multipage entry form
that ultimately gets processed
as a single form.
28. Processing commands
Command controller are used to perform work based
on parameters such as binding parameters to business
objects E.g. AbstractCommandController.
Command controllers can automatically bind request
parameters to a command object.
They can also be wired to plug in validators to ensure
that the parameters are valid.
30. Command Controller
The handle() method of is the main execution method
for AbstractCommandController.
The handle() method takes an Object that is the
controller’s command along with HttpServletRequest
and HttpServletResponse.
A command object is a bean (POJO) that is meant to
hold request parameters for easy access.
Before the handle() method is called, Spring will
attempt to match any parameters passed in the request
to properties in the command object.
31. Form Controller
Form Controller is a single controller to handle both form display
and form processing.
Form controllers extend the command controllers by adding the
functionality to display a form when an HTTP GET request is
received and process the form when an HTTP POST is received.
Further, if any errors occur in processing the form, the controller
will know to redisplay the form so that the user can correct the
errors and resubmit.
33. Form Controller
When the form controller receives an HTTP GET
request, it will direct the request to the form view.
When the form controller receives an HTTP POST
request, the onSubmit() method will process the form
submission.
The form uses the nested property within a command
class instance as part of the form-backing object.
hence, the formBackingObject() method is overidden
to set this property.
The onSubmit() method handles the form submission
(an HTTP POST request) by passing the command
object (which is an instance of Rant) to the method of
the injected Service Object reference.
34. Form Controller
The form controller in the context configuration file as follows:
<bean id="addRantController"
class="com.roadrantz.mvc.AddRantFormController">
<property name="formView" value="addRant" />
<property name="successView" value="rantAdded" />
<property name="rantService" ref="rantService" />
</bean>
The formView property is the logical name of a view to display
when the controller receives an HTTP GET request or when any
errors are encountered.
The successView is the logical name of a view to display when
the form has been submitted successfully.
A view resolver use these values to locate the View object that
renders the output to the user.
35. Input Validation
The org.springframework.validation.Validator interface
accommodates validation for Spring MVC.
public interface Validator {
void validate(Object obj, Errors errors);
boolean supports(Class clazz);
}
The validate() method examines fields of the object and
reject invalid values via Error object (using
ValidationUtils.rejectIfEmpty() method).
The supports() method is used to help Spring determine
whether the validator can be used for a given class.
36. Commons Validator
It enables to declare validation rules outside of Java
code.
Spring uses the validation module (which uses Jakarta
Commons Validator) in Spring Modules project as
implementation for declarative validation.
The validation module can be used in the application
by making the springmodules-validator.jar file
available in the application’s classpath.
Spring Modules provides an implementation of
Validator called DefaultBeanValidator.
37. DefaultBeanValidator
DefaultBeanValidator delegates to Commons Validator to
validate field values instead of doing any actual validation.
DefaultBeanValidator has a validatorFactory property which is
wired with a reference to a validatorFactory bean.
The validatorFactory bean is declared as follows:
<bean id="validatorFactory" class=
"org.springmodules.commons.validator.DefaultValidatorFactory"
>
<property name="validationConfigLocations">
<list> <value>WEB-INF/validator-rules.xml</value>
<value>WEB-INF/validation.xml</value>
</list>
</property>
</bean>
38. DefaultBeanValidator
DefaultValidatorFactory is a class that loads the
Commons Validator configuration on behalf of
DefaultBeanValidator.
The validationConfigLocations property takes a list of
one or more validation configurations.
The validator-rules.xml file contains a set of
predefined validation rules for common validation
and comes with the Commons Validator distribution.
The validation.xml, defines application-specific
validation rules that apply directly to the sample
application.
40. AbstractWizardFormController
A wizard form controller is a special type of form
controller that collects form data from multiple pages
into a single command object for processing
41. public class MotoristRegistrationController extends
AbstractWizardFormController {
public MotoristRegistrationController() { Sets command and class name }
protected Object formBackingObject(HttpServletRequest request) throws
Exception {
Motorist formMotorist = new Motorist();
List<Vehicle> vehicles = new ArrayList<Vehicle>();
vehicles.add(new Vehicle());
formMotorist.setVehicles(vehicles);
return formMotorist;
}
protected Map referenceData(HttpServletRequest request,
Object command, Errors errors, int page) throws Exception {
Motorist motorist = (motorist) command;
Map refData = new HashMap(); // Increments next vehicle pointer
if(page == 1 && request.getParameter("_target1") != null) {
refData.put("nextVehicle", motorist.getVehicles().size() - 1); }
return refData;
}
43. MotoristRegistrationController
The formBackingObject() method is overridden to set the
vehicles property with a list of Vehicle objects as the
motorist can also register for one or more vehicles.
The list is also started with a blank Vehicle object for the
form to populate.
The referenceData() is overridden to make the index of the
next vehicle available to the form.
The processFinish() method which is a mandatory method
is called to finalize the form when the user has finished
completing it.
The processFinish() method sends the data in the Motorist
object to addMotorist() on the injected RantService object.
44. WizardFormController Configuration
<bean id="registerMotoristController"
class="com.roadrantz.mvc.MotoristRegistrationController">
<property name="rantService" ref="rantService" />
<property name="pages">
<list>
<value>motoristDetailForm</value>
<value>motoristVehicleForm</value>
<value>motoristConfirmation</value>
<value>redirect:home.htm</value>
</list>
</property>
</bean>
A list of logical view names is given to the pages property. These
names will ultimately be resolved into a View object by a view
resolver.
45. WizardFormController Configuration
The first page to be shown in any wizard controller will be the
first page in the list given to the pages property.
To determine which page to go to next,
AbstractWizardFormController consults its getTargetPage()
method which returns an index into the zero-based list of pages
given to the pages property.
The default implementation of getTargetPage() determines
which page to go to next based on a parameter in the request
whose name begins with _target and ends with a number (i.e.
index into the pages list).
Another special request parameter called _finish indicates to
AbstractWizardFormController that the user has finished filling
out the form and wants to submit the information for processing.
46. Wizard Controller Cancellation
A cancel button has _cancel as its name so that, which when
passed to the AbstractWizardFormController as the parameter, it
passes the control to the processCancel() method.
By default, processCancel() throws an exception indicating that
the cancel operation is not supported, hence it must be
overridden.
protected ModelAndView processCancel(HttpServletRequest
request,
HttpServletResponse response, Object command,
BindException bindException) throws Exception {
return new ModelAndView(getSucessView());
}
47. Validating the Wizard
Wizard controllers validate the command object a page at a time,
instead of validating the command object all at once.
Every time when a page transition occurs the validatePage()
method is called.
The default implementation of validatePage() is empty (i.e., no
validation), which can be overridden.
protected void validatePage(Object command, Errors errors, int
page) {
Motorist motorist = (Motorist) command;
MotoristValidator validator = (MotoristValidator) getValidator();
if(page == 0) {
validator.validateEmail(motorist.getEmail(), errors);
}
}
48. Validating the Wizard
<bean id="registerMotoristController"
class="com.roadrantz.mvc.MotoristRegistrationController">
<property name="rantService" ref="rantService" />
<property name="pages">
<list>
<value>motoristDetailForm</value>
<value>motoristVehicleForm</value>
<value>motoristConfirmation</value>
<value>redirect:home.htm</value>
</list>
</property>
<property name="validator">
<bean class="com.roadrantz.mvc.MotoristValidator" />
</property>
</bean>
Wizard controllers never call the standard validate() method of their Validator
object, as validate() method validates the entire command object as a whole,
whereas it is understood that the command objects in a wizard will be
validated a page at a time.
49. Throwaway Controller
public interface ThrowawayController {
ModelAndView execute() throws Exception; }
Throwaway controllers act as their own command
object instead of giving HttpServletRequest and
command object parameters.
50. Throwaway Controller
public class RantsForDayController implements ThrowawayController {
private Date day;
public ModelAndView execute() throws Exception {
List<Rant> dayRants = rantService.getRantsForDay(day);
return new ModelAndView("dayRants", "rants", dayRants);
}
public void setDay(Date day) {
this.day = day;
}
private RantService rantService;
public void setRantService(RantService rantService) {
this.rantService = rantService;
}
}
51. Throwaway Controller
<bean id="rantsForDayController"
class="com.roadrantz.mvc.RantsForDayController"
scope="prototype">
<property name="rantService" ref="rantService" />
</bean>
Before RantsForDayController handles the request, Spring calls the
setDay() method, passing in the value of the day request parameter
before RantsForDayController handles the request.
Once in the execute() method, RantsForDayController simply passes
day to rantService and getRantsForDay() retrieves the list of rants for
that day.
One thing that remains the same as the other controllers is that the
execute() method must return a ModelAndView object when it has
finished.
The scope attribute of the Throwaway Controller is set to prototype, as
it is recycled between requests and should not be singleton by default.
Also its properties (which should reflect the request parameter values)
may also be reused. Setting scope to prototype tells Spring to throw the
controller away after it has been used and to instantiate a fresh instance
for each request.
52. Throwaway Controller
DispatcherServlet knows how to dispatch requests to controllers
in the Controller interface hierarchy by using a default handler
adapter.
ThrowawayController isn’t in the same hierarchy as Controller,
hence DispatcherServlet needs to use a different handler adapter.
Specifically, you must configure
ThrowawayControllerHandlerAdapter as follows:
<bean id="throwawayHandler"
class="org.springframework.web.servlet.mvc.throwaway.Throwa
wayControllerHandlerAdapter"/>
Declaring the throwawayHandler bean, lets DispatcherServlet to
replace its default handler adapter with
ThrowawayControllerHandlerAdapter.
53. Throwaway Controller
If the application uses both throwaway and regular
controllers alongside each other then both
SimpleControllerHandlerAdapter and
ThrowawayControllerHandlerAdapter should be
declared.
<bean id="simpleHandler"
class="org.springframework.web.servlet.mvc.
SimpleControllerHandlerAdapter"/>
54. Handling exceptions
SimpleMappingExceptionResolver handles exceptions
thrown from the controller.
SimpleMappingExceptionResolver is configured as follows
to handle any java.lang.Exceptions thrown from Spring
MVC controllers:
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.
SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">friendlyError</prop>
</props>
</property>
</bean>
55. Handling exceptions
The exceptionMappings property takes a
java.util.Properties that contains a mapping of fully
qualified exception class names to logical view names.
The base Exception class is mapped to the View whose
logical name is friendlyError so that if any errors are
thrown, users won’t have to see an ugly stack trace but
the Friendly Error message in the friendlyError view.
When a controller throws an Exception,
SimpleMappingExceptionResolver resolves it to
friendlyError, which in turn resolves to a View using
the configured view resolver(s).