Spring Study Notes - Copyright © 2010 Gavin Lasnitzki Index   Notes   Objectives
Using Spring in Web Applications

III. The Web

13. Web MVC framework

13.1. Introduction Key

Objectives: 9.1 Goals of effective web application architecture , 9.2 Bootstrapping a Spring-based application , 9.3 Accessing a Spring-based application , 9.4 Spring MVC Request Processing Lifecycle

Controller

The framework is designed around a DispatcherServlet that dispatches requests to handlers.
The default handler is a very simple Controller interface, just offering the "ModelAndView handleRequest(request,response)" method.
Spring offers both a traditional Controller implementation (using sub-classes) and an annotation implementation.

Model
Spring Web MVC allows you to use any object as a command or form object.
Spring's data binding is highly flexible.
It treats type mismatches as validation errors that can be evaluated by the application, not as system errors (no need to use String properties).

View
Spring's view resolution is extremely flexible.
View name resolution is highly configurable, either via bean names, via a properties file, or via your own ViewResolver implementation.

 

13.1.1. Pluggability of other MVC implementations

You can integrate the web MVC framework of your choice with Spring easily.

13.1.2. Features of Spring Web MVC Key

  • Clear separation of roles - controller, validator, command object, form object, model object, DispatcherServlet, handler mapping, view resolver, etc. Each role can be fulfilled by a specialized object.
  • Powerful and straightforward configuration of both framework and application classes as JavaBeans, including easy referencing across contexts, such as from web controllers to business objects and validators.
  • Adaptability, non-intrusiveness. Use whatever controller subclass you need (plain, command, form, wizard, multi-action, or a custom one) for a given scenario instead of deriving from a single controller for everything.
  • Reusable business code - no need for duplication. You can use existing business objects as command or form objects instead of mirroring them in order to extend a particular framework base class.
  • Customizable binding and validation - type mismatches as application-level validation errors that keep the offending value, localized date and number binding, etc instead of String-only form objects with manual parsing and conversion to business objects.
  • Customizable handler mapping and view resolution - handler mapping and view resolution strategies range from simple URL-based configuration, to sophisticated, purpose-built resolution strategies.
  • Flexible model transfer - model transfer via a name/value Map supports easy integration with any view technology.
  • Customizable locale and theme resolution, support for JSPs with or without Spring tag library, support for JSTL, support for Velocity without the need for extra bridges, etc.
  • A simple yet powerful JSP tag library known as the Spring tag library that provides support for features such as data binding and themes. The custom tags allow for maximum flexibility in terms of markup code.
  • A JSP form tag library, introduced in Spring 2.0, that makes writing forms in JSP pages much easier.
  • Beans whose lifecycle is scoped to the current HTTP request or HTTP Session.

13.2. The DispatcherServlet Key

Objectives: 9.5 DispatcherServlet

The Spring framework is request-driven, designed around a central servlet (Front Controller design pattern) that dispatches requests to controllers. Question
It integrated with the Spring IoC container and allows you to use all other Spring features.

DispatchServlet

 

Standard J2EE servlet configuration:

 

Each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext.
These inherited beans defined can be overridden in the servlet-specific scope, and new scope-specific beans can be defined local to a given servlet instance.
The framework will, on initialization of a DispatcherServlet, look for a file named [servlet-name]-servlet.xml in the WEB-INF directory. Question

The WebApplicationContext is an extension of the plain ApplicationContext.
It is capable of resolving themes.
It knows which servlet it is associated with (by having a link to the ServletContext) and can be retrieved by using static methods on the RequestContextUtils class.

DispatcherServlet has special beans it uses in order to be able to process requests and render the appropriate views: Question

  • Controllers are the components that form the 'C' part of the MVC.
  • Handler mappings handle the execution of a list of pre- and post-processors and controllers that will be executed if they match certain criteria (for instance a matching URL specified with the controller).
  • View resolvers are components capable of resolving view names to views.
  • A locale resolver is a component capable of resolving the locale a client is using, in order to be able to offer internationalized views.
  • A theme resolver is capable of resolving themes your web application can use, for example, to offer personalized layouts.
  • A multipart file resolver offers the functionality to process file uploads from HTML forms.
  • Handler exception resolvers offer functionality to map exceptions to views or implement other more complex exception handling code.

DispatcherServlet initialization parameters:

Parameter Explanation
contextClass Class that implements WebApplicationContext, which will be used to instantiate the context used by this servlet. If this parameter isn't specified, the XmlWebApplicationContext will be used. Question
contextConfigLocation String which is passed to the context instance (specified by contextClass) to indicate where context(s) can be found. The string is potentially split up into multiple strings (using a comma as a delimiter) to support multiple contexts (in case of multiple context locations, of beans that are defined twice, the latest takes precedence).
namespace the namespace of the WebApplicationContext. Defaults to [servlet-name]-servlet.

13.3. Controllers Key

Controllers interpret user input and transform such input into a sensible model which will be represented to the user by the view.

The org.springframework.web.servlet.mvc.Controller

 

Controller hierarchy:

controllers

13.3.1. AbstractController and WebContentGenerator

AbstractController provides basic infrastructure support.

Feature Explanation
supportedMethods indicates what methods this controller should accept. Usually this is set to both GET and POST, but you can modify this to reflect the method you want to support. If a request is received with a method that is not supported by the controller, the client will be informed of this (expedited by the throwing of a ServletException).
requireSession indicates whether or not this controller requires a HTTP session to do its work. If a session is not present when such a controller receives a request, the user is informed of this by a ServletException being thrown.
synchronizeOnSession use this if you want handling by this controller to be synchronized on the user's HTTP session.
cacheSeconds when you want a controller to generate a caching directive in the HTTP response, specify a positive integer here. By default the value of this property is set to -1 so no caching directives will be included in the generated response.
useExpiresHeader tweaks your controllers to specify the HTTP 1.0 compatible "Expires" header in the generated response. By default the value of this property is true.
useCacheHeader tweaks your controllers to specify the HTTP 1.1 compatible "Cache-Control" header in the generated response. By default the value of this property is true.

When using the AbstractController as the baseclass override the handleRequestInternal(HttpServletRequest, HttpServletResponse) method.

13.3.2. Other simple controllers

ParameterizableViewController - defines a viewName property with both getter and setter methods. It can render a view to users without any processing logic.

UrlFilenameViewController - inspects the URL and retrieves the filename of the file request and uses that as a viewname.

13.3.3. The MultiActionController

A MultiActionController minimizes the number of controllers by supporting the aggregation of multiple request-handling
methods into one controller.
It is capable of mapping requests to method names and then invoking the correct method to handle a particular request.

Two styles:

  • Subclass the MultiActionController and specify the methods that will be resolved by the MethodNameResolver on your subclass.
  • Define a delegate object, on which methods resolved by the MethodNameResolver will be invoked.

Methods must conform to the following signature:
Note: The session must be the third argument, and an object to be bound must always be the final argument.

 

Return Type Question

  • void - handler will write the response.
  • Map - view name translator will provide the view name based on the request and the model will consist of the Map's entries.
  • ModelAndView - handler will provide the view name and the model.

MethodNameResolver implementations

  • InternalPathMethodNameResolver (default) - interprets the final filename from the request path and uses that as the method name.
    For example: http://www.sf.net/test.view invokes test()
  • ParameterMethodNameResolver - interprets a request parameter as the name of the method that is to be invoked.
    For example: http://www.sf.net/index.view?method=test invokes test()
  • PropertiesMethodNameResolver - uses a user-defined Properties object with request URLs mapped to method names
    For example: If the Properties contain '/index.html=test', http://www.sf.net/index.html invokes test()

You may also declare custom methods for handling Exceptions that occur during request handling.

13.3.4. Command controllers

Command controllers provide a way to interact with data objects and dynamically bind parameters from the HttpServletRequest to the data object specified.

Implementations include:

  • AbstractCommandController - a command controller you can use to create your own command controller,
    capable of binding request parameters to a data object you specify.
  • AbstractFormController - an abstract controller offering form submission support.
    Using this controller you can model forms and populate them using a command object you retrieve in the controller.
    After a user has filled the form, the AbstractFormController binds the fields, validates the command object, and hands the object back to the controller to take the appropriate action.
    Supported features are: invalid form submission (resubmission), validation, and normal form workflow
  • SimpleFormController - a form controller that provides even more support when creating a form with a corresponding command object.
    It let's you specify a command object, a viewname for the form, a viewname for page you want to show the user when form submission has succeeded, and more.
  • AbstractWizardFormController

Specify command (model) object

  • Call setCommandClass() from the constructor with the class of your command object
  • Implement the formBackingObject() method

13.4. Handler mappings

Objectives: 9.7 Handler Mappings

A handler is an arbitrary Java object that can handle web requests. Key
The most typical handler used in Spring MVC for handling web requests is a controller

Using a handler mapping you can map incoming web requests to appropriate handlers.

AbstractHandlerMapping has the following properties

  • interceptors: the list of interceptors to use.
  • defaultHandler: the default handler to use, when this handler mapping does not result in a matching handler.
  • order: based on the value of the order property
  • alwaysUseFullPath: if this property is set to true, Spring will use the full path within the current servlet context to find an appropriate handler. If this property is set to false (the default), the path within the current servlet mapping will be used. For example, if a servlet is mapped using /testing/* and the alwaysUseFullPath property is set to true, /testing/viewPage.html would be used, whereas if the property is set to false, /viewPage.html would be used.
  • urlDecode
  • lazyInitHandlers: allows for lazy initialization of singleton handlers (prototype handlers are always lazily
    initialized)

13.4.1. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping maps incoming HTTP requests to names of beans (in the web application context).
Defaults to BeanNameUrlHandlerMapping if no handler mapping is found in the context.

To handle URL: /editaccount.form

13.4.2. SimpleUrlHandlerMapping

The SimpleUrlHandlerMapping is more powerful.
This mapping is configurable in the application context and has Ant-style path matching capabilities

13.4.3. Intercepting requests - the HandlerInterceptor interface

Interceptors must implement HandlerInterceptor.
Interceptors can be called:

  • before the actual handler will be executed (preHandle). Returning true continues with the execution.
  • after the handler is executed (postHandle)
  • after the complete request has finished (afterCompletion)

Use HandlerInterceptorAdapter to make implementation easier.


13.5. Views and resolving them Key

Objectives: 9.7 Handler Mappings

Supports JSPs, JSTL, Velocity, Freemarker, XSLT, Excel, PDF..

The ViewResolver provides a mapping between view names and actual views.
The View interface addresses the preparation of the request and hands the request over to one of the view technologies.

13.5.1. Resolving views - the ViewResolver interface

ViewResolver Description
AbstractCachingViewResolver An abstract view resolver which takes care of caching views.
XmlViewResolver Accepts a configuration file written in XML with the same DTD as Spring's XML bean factories.
The default configuration file is /WEB-INF/views.xml.
ResourceBundleViewResolver Uses bean definitions in a ResourceBundle, specified by the bundle basename.
The default file name is views.properties.
The value of the property [viewname].class is the view class and the value of the property [viewname].url as the view url.
UrlBasedViewResolver Direct resolution of symbolic view names to URLs, without an explicit mapping definition.
InternalResourceViewResolver A convenience subclass of UrlBasedViewResolver that supports InternalResourceView (i.e. Servlets and JSPs), and subclasses such as JstlView and TilesView.
VelocityViewResolver / FreeMarkerViewResolver A convenience subclass of UrlBasedViewResolver that supports VelocityView (i.e. Velocity templates) or FreeMarkerView respectively and custom subclasses of them.

 

13.5.2. Chaining ViewResolvers

If a specific view resolver does not result in a view, Spring will inspect the context to see if other view resolvers are configured.
If there are additional view resolvers, it will continue to inspect them.
If not, it will throw an Exception.

NOTE: The InternalResourceViewResolver will always return a view, so it must be put at the end of the chain.

13.5.3. Redirecting to views

13.5.3.1. RedirectView

Controller to create and return an instance of Spring's RedirectView.

13.5.3.2. The redirect: prefix

If a view name is returned which has the prefix "redirect:", then UrlBasedViewResolver (and all subclasses) will recognize this as a special indication that a redirect is needed. The rest of the view name will be treated as the redirect URL.

13.5.3.3. The forward: prefix

13.6. Using locales

Using the RequestContext.getLocale() method, you can always retrieve the locale that was resolved by the locale resolver.

13.6.1. AcceptHeaderLocaleResolver

This locale resolver inspects the accept-language header in the request that was sent by the browser of the client.
Usually this header field contains the locale of the client's operating system.

13.6.2. CookieLocaleResolver

This locale resolver inspects a Cookie that might exist on the client, to see if a locale is specified.

13.6.3. SessionLocaleResolver

The SessionLocaleResolver allows you to retrieve locales from the session that might be associated with the user's request.

13.6.4. LocaleChangeInterceptor

You can build in changing of locales using the LocaleChangeInterceptor.
This interceptor needs to be added to one of the handler mappings.
It will detect a parameter in the request and change the locale.

13.7. Using themes

13.7.1. Introduction

13.7.2. Defining themes

Set up a org.springframework.ui.context.ThemeSource.

13.7.3. Theme resolvers

Implemented theme resolvers

  • FixedThemeResolver
  • SessionThemeResolver
  • CookieThemeResolver

or use a ThemeChangeInterceptor.

13.8. Spring's multipart (fileupload) support

13.8.1. Introduction

13.8.2. Using the MultipartResolver

13.8.3. Handling a file upload in a form

13.9. Handling exceptions

The SimpleMappingExceptionResolver. This resolver enables you to take the class name of any exception that might be thrown and map it to a view name.

13.10. Convention over configuration Key

Allows rapid prototyping.
Consistency across a codebase.

13.10.1. The Controller - ControllerClassNameHandlerMapping

The ControllerClassNameHandlerMapping class is a HandlerMapping implementation that uses a convention to determine the mapping between request URLs and the Controller instances that are to handle those requests.

Example: WelcomeController maps to the '/welcome*' request URL

13.10.2. The Model - ModelMap (ModelAndView)

Objects can be added to the model without specifying their name.

Example:
An x.y.User instance added will have the name 'user'.
An x.y.User[] array with one or more x.y.User elements added will have the name 'userList'.

13.10.3. The View - RequestToViewNameTranslator

(Default) The DefaultRequestToViewNameTranslator maps request URLs to logical view names.

Example: URL of 'http://localhost/registration.html' will result in a logical view name of 'registration'.

 

13.11. Annotation-based controller configuration Key

Objectives: 9.6 Handlers

13.11.1. Setting up the dispatcher for annotation support

Enabled by default if you use DisplatcherServlet.
Add DefaultAnnotationHandlerMapping (class level annotations) and AnnotationMethodHandlerAdapter (method level annotations) to context if you use a custom dispatcher or need to customize the mapping strategy.

13.11.2. Defining a controller with @Controller Question

The basic purpose of the @Controller annotation is to act as a stereotype for the annotated class.
The dispatcher will scan such annotated classes for mapped methods, detecting @RequestMapping annotations.

Use the following to scan for the annotation:

13.11.3. Mapping requests with @RequestMapping

The @RequestMapping annotation is used to map URLs onto an entire class or a particular handler method.

13.11.3.1. Advanced @RequestMapping options

13.11.4. Supported handler method arguments and return types

Handler methods which are annotated with @RequestMapping are allowed to have very flexible signatures.
They may have arguments of the following types, in arbitrary order (except for validation results, which need to follow right after the corresponding command object, if desired):

  • Request and/or response objects (Servlet API). You may choose any specific request/response type, e.g. ServletRequest / HttpServletRequest.
  • Session object (Servlet API): of type HttpSession. An argument of this type will enforce the presence of a corresponding session. As a consequence, such an argument will never be null. Note that session access may not be thread-safe, in particular in a Servlet environment: Consider switching the AnnotationMethodHandlerAdapter's "synchronizeOnSession" flag to "true" if multiple requests are allowed to access a session concurrently.
  • org.springframework.web.context.request.WebRequest or org.springframework.web.context.request.NativeWebRequest. Allows for generic request parameter access as well as request/session attribute access, without ties to the native Servlet/Portlet API.
  • java.util.Locale for the current request locale (determined by the most specific locale resolver available, i.e. the configured LocaleResolver in a Servlet environment).
  • java.io.InputStream / java.io.Reader for access to the request's content. This will be the raw InputStream/Reader as exposed by the Servlet API.
  • java.io.OutputStream / java.io.Writer for generating the response's content. This will be the raw OutputStream/Writer as exposed by the Servlet API.
  • @RequestParam annotated parameters for access to specific Servlet request parameters. Parameter values will be converted to the declared method argument type.
  • java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap for enriching the implicit model that will be exposed to the web view.
  • Command / form objects to bind parameters to: as bean properties or fields, with customizable type conversion, depending on @InitBinder methods and/or the HandlerAdapter configuration - see the "webBindingInitializer" property on AnnotationMethodHandlerAdapter. Such command objects along with their validation results will be exposed as model attributes, by default using the non-qualified command class name in property notation (e.g. "orderAddress" for type "mypackage.OrderAddress"). Specify a parameter-level ModelAttribute annotation for declaring a specific model attribute name.
  • org.springframework.validation.Errors / org.springframework.validation.BindingResult validation results for a preceding command/form object (the immediate preceding argument).
  • org.springframework.web.bind.support.SessionStatus status handle for marking form processing as complete (triggering the cleanup of session attributes that have been indicated by the @SessionAttributes annotation at the handler type level).

The following return types are supported for handler methods:

  • A ModelAndView object, with the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.
  • A Model object, with the view name implicitly determined through a RequestToViewNameTranslator and the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.
  • A Map object for exposing a model, with the view name implicitly determined through a RequestToViewNameTranslator and the model implicitly enriched with command objects and the results of @ModelAttribute annotated reference data accessor methods.
  • A View object, with the model implicitly determined through command objects and @ModelAttribute annotated reference data accessor methods. The handler method may also programmatically enrich the model by declaring a Model argument.
  • A String value which is interpreted as view name, with the model implicitly determined through command objects and @ModelAttribute annotated reference data accessor methods.
  • void if the method handles the response itself (by writing the response content directly, declaring an argument of type ServletResponse / HttpServletResponse for that purpose)
  • Any other return type will be considered as single model attribute to be exposed to the view, using the attribute name specified through @ModelAttribute at the method level (or the default attribute name based on the return type's class name otherwise).

 

13.11.5. Binding request parameters to method parameters with @RequestParam

The @RequestParam annotation is used to bind request parameters to a method parameter in your controller.

13.11.6. Providing a link to data from the model with @ModelAttribute

When placed on a method parameter, @ModelAttribute is used to map a model attribute to the specific, annotated method parameter.

@ModelAttribute is also used at the method level to provide reference data for the model.

13.11.7. Specifying attributes to store in a Session with @SessionAttributes

The type-level @SessionAttributes annotation declares session attributes used by a specific handler.

13.11.8. Customizing WebDataBinder initialization

To customize request parameter binding with PropertyEditors, etc. via Spring's WebDataBinder, you can either use @InitBinder-annotated methods within your controller or externalize your configuration by providing a custom WebBindingInitializer.

13.11.8.1. Customizing data binding with @InitBinder

13.11.8.2. Configuring a custom WebBindingInitializer

13.12. Further Resources

14. View technologies

Excluded from Exam

14.1. Introduction

14.2. JSP & JSTL

14.2.1. View resolvers

14.2.2. 'Plain-old' JSPs versus JSTL

14.2.3. Additional tags facilitating development

14.2.4. Using Spring's form tag library

14.2.4.1. Configuration

14.2.4.2. The form tag

14.2.4.3. The input tag

14.2.4.4. The checkbox tag

14.2.4.5. The checkboxes tag

14.2.4.6. The radiobutton tag

14.2.4.7. The radiobuttons tag

14.2.4.8. The password tag

14.2.4.9. The select tag

14.2.4.10. The option tag

14.2.4.11. The options tag

14.2.4.12. The textarea tag

14.2.4.13. The hidden tag

14.2.4.14. The errors tag

14.3. Tiles

14.3.1. Dependencies

14.3.2. How to integrate Tiles

14.3.2.1. UrlBasedViewResolver

14.3.2.2. ResourceBundleViewResolver

14.3.2.3. SimpleSpringPreparerFactory and SpringBeanPreparerFactory

14.4. Velocity & FreeMarker

14.4.1. Dependencies

14.4.2. Context configuration

14.4.3. Creating templates

14.4.4. Advanced configuration

14.4.4.1. velocity.properties

14.4.4.2. FreeMarker

14.4.5. Bind support and form handling

14.4.5.1. The bind macros

14.4.5.2. Simple binding

14.4.5.3. Form input generation macros

14.4.5.4. HTML escaping and XHTML compliance

14.5. XSLT

14.5.1. My First Words

14.5.1.1. Bean definitions

14.5.1.2. Standard MVC controller code

14.5.1.3. Convert the model data to XML

14.5.1.4. Defining the view properties

14.5.1.5. Document transformation

14.5.2. Summary

14.6. Document views (PDF/Excel)

14.6.1. Introduction

14.6.2. Configuration and setup

14.6.2.1. Document view definitions

14.6.2.2. Controller code

14.6.2.3. Subclassing for Excel views

14.6.2.4. Subclassing for PDF views

14.7. JasperReports

14.7.1. Dependencies

14.7.2. Configuration

14.7.2.1. Configuring the ViewResolver

14.7.2.2. Configuring the Views

14.7.2.3. About Report Files

14.7.2.4. Using JasperReportsMultiFormatView

14.7.3. Populating the ModelAndView

14.7.4. Working with Sub-Reports

14.7.4.1. Configuring Sub-Report Files

14.7.4.2. Configuring Sub-Report Data Sources

14.7.5. Configuring Exporter Parameters

15. Integrating with other web frameworks

Excluded from Exam

15.1. Introduction

15.2. Common configuration

15.3. JavaServer Faces 1.1 and 1.2

15.3.1. DelegatingVariableResolver (JSF 1.1/1.2)

15.3.2. SpringBeanVariableResolver (JSF 1.1/1.2)

15.3.3. SpringBeanFacesELResolver (JSF 1.2+)

15.3.4. FacesContextUtils

15.4. Apache Struts 1.x and 2.x

15.4.1. ContextLoaderPlugin

15.4.1.1. DelegatingRequestProcessor

15.4.1.2. DelegatingActionProxy

15.4.2. ActionSupport Classes

15.5. WebWork 2.x

15.6. Tapestry 3.x and 4.x

15.6.1. Injecting Spring-managed beans

15.6.1.1. Dependency Injecting Spring Beans into Tapestry pages

15.6.1.2. Component definition files

15.6.1.3. Adding abstract accessors

15.6.1.4. Dependency Injecting Spring Beans into Tapestry pages - Tapestry 4.x style

15.7. Further Resources

16. Portlet MVC Framework

Excluded from Exam

16.1. Introduction

16.1.1. Controllers - The C in MVC

16.1.2. Views - The V in MVC

16.1.3. Web-scoped beans

16.2. The DispatcherPortlet

16.3. The ViewRendererServlet

16.4. Controllers

16.4.1. AbstractController and PortletContentGenerator

16.4.2. Other simple controllers

16.4.3. Command Controllers

16.4.4. PortletWrappingController

16.5. Handler mappings

16.5.1. PortletModeHandlerMapping

16.5.2. ParameterHandlerMapping

16.5.3. PortletModeParameterHandlerMapping

16.5.4. Adding HandlerInterceptors

16.5.5. HandlerInterceptorAdapter

16.5.6. ParameterMappingInterceptor

16.6. Views and resolving them

16.7. Multipart (file upload) support

Spring offers support for multi-part forms. Question

16.7.1. Using the PortletMultipartResolver

16.7.2. Handling a file upload in a form

16.8. Handling exceptions

16.9. Annotation-based controller configuration

16.9.1. Setting up the dispatcher for annotation support

16.9.2. Defining a controller with @Controller

16.9.3. Mapping requests with @RequestMapping

16.9.4. Supported handler method arguments

16.9.5. Binding request parameters to method parameters with @RequestParam

16.9.6. Providing a link to data from the model with @ModelAttribute

16.9.7. Specifying attributes to store in a Session with @SessionAttributes

16.9.8. Customizing WebDataBinder initialization

16.9.8.1. Customizing data binding with @InitBinder

16.9.8.2. Configuring a custom WebBindingInitializer

16.10. Portlet application deployment