org.springframework.web.servlet.mvc
Class AbstractFormController

org.springframework.context.support.ApplicationObjectSupport
  |
  +--org.springframework.web.context.support.WebApplicationObjectSupport
        |
        +--org.springframework.web.servlet.support.WebContentGenerator
              |
              +--org.springframework.web.servlet.mvc.AbstractController
                    |
                    +--org.springframework.web.servlet.mvc.BaseCommandController
                          |
                          +--org.springframework.web.servlet.mvc.AbstractFormController
Direct Known Subclasses:
AbstractWizardFormController, SimpleFormController

public abstract class AbstractFormController
extends BaseCommandController

Form controller that autopopulates a form bean from the request. This, either using a new bean instance per request, or using the same bean when the sessionForm property has been set to true. This class is the base class for both framework subclasses like SimpleFormController and AbstractWizardFormController, and custom form controllers you can provide yourself.

Both form- input-views and after-submission-views have to be provided programmatically. To provide those views using configuration properties, use the SimpleFormController.

Subclasses need to override showForm to prepare the form view, and processFormSubmission to handle submit requests. For the latter, binding errors like type mismatches will be reported via the given "errors" holder. For additional custom form validation, a validator (property inherited from BaseCommandController) can be used, reporting via the same "errors" instance.

Comparing this Controller to the Struts notion of the Action shows us that with Spring, you can use any ordinary JavaBeans or database backed JavaBean without having to implement a framework specific class (in case of Struts, this is ActionForm). More complex properties of JavaBeans (Dates, Locales, but also your own application specific or compound types) can be represented and submitted to the controller, by using the notion of java.beans.PropertyEditors. For more information on that subject, see the workflow of this controller and the explanation of the BaseCommandController.

Workflow (and that defined by superclass):

  1. GET request on the controller is received
  2. call to formBackingObject() which by default, returns an instance of the commandClass that has been configured (see the properties the superclass exposes), but can also be overriden to - for instance - retrieve an object from the database (that - for instance - needs to be modified using the form)
  3. call to initBinder() which allows you to register custom editors for certain fields (often properties of non-primitive or non-Sring types) or the command class. This render appropriate Strings for for instance locales
  4. binding of the ServletRequestDataBinder in the request to be able to use the property editors in the form rendering (only if bindOnNewForm is set to true)
  5. call to showForm() to return a View that should be rendered (typically the view that renders the form). This method has be overridden in extending classes
  6. call to referenceData() to allow you to bind any relevant reference data you might need when editing a form (for instance a List of Locale objects you're going to let the user select one from)
  7. model gets exposed and view gets rendered. Continue after user has filled in form
  8. POST request on the controller is received
  9. if sessionForm is not set, getCommand() is called to retrieve a command class. Otherwise, the controller tries to find the command object which is already bound in the session. If it cannot find the object, it'll do a call to handleInvalidSubmit which - by default - tries to create a new command class and resubmit the form
  10. controller tries to put all parameters from the request into the JavaBeans (command object) and if validateOnBinding is set, validation will occur
  11. call to onBindAndValidate() which allows you to do custom processing after binding and validation (for instance to perform database persistency)
  12. call to processFormSubmission which, in implementing classes returns a sort of successview, for instance congratulating the user with a successfull form submission

Note that by default POST requests are treated as form submissions. This can be customized by overriding isFormSubmission. Custom binding can be achieved either by registering custom property editors before binding in an initBinder implementation, or by custom bean population from request parameters after binding in an onBindAndValidate implementation.

In session form mode, a submission without an existing form object in the session is considered invalid, like in case of a resubmit/reload by the browser. The handleInvalidSubmit method is invoked then, trying a resubmit by default. It can be overridden in subclasses to show respective messages or redirect to a new form, in order to avoid duplicate submissions. The form object in the session can be considered a transaction token in this case.

Note that views should never retrieve form beans from the session but always from the request, as prepared by the form controller. Remember that some view technologies like Velocity cannot even access a HTTP session.

Exposed configuration properties (and those defined by superclass):
name default description
bindOnNewForm false Indicates whether to bind servletrequestparameters as well when creating a new form. If set to true this will happen, if set to false, the parameters will only be bound on formsubmissions
sessionForm false Indicates whether or not the command object should be bound onto the session when a user asks for a new form. This allows you to for instance retrieve an object from the database, let the user edit it, and then persist it again. If this is set to false, a new command object will be created on all requests (both requests for the form and submissions of the form)

Author:
Rod Johnson, Juergen Hoeller, Alef Arendsen
See Also: SimpleFormController, AbstractWizardFormController

Fields inherited from class org.springframework.web.servlet.mvc.BaseCommandController
DEFAULT_COMMAND_NAME

Fields inherited from class org.springframework.web.servlet.support.WebContentGenerator
HEADER_CACHE_CONTROL, HEADER_EXPIRES, HEADER_PRAGMA, METHOD_GET, METHOD_POST

Constructor Summary
AbstractFormController()
          Create a new AbstractFormController.

Method Summary
 final voidsetBindOnNewForm(boolean bindOnNewForm)
          Set if request parameters should be bound to the form object in case of a non-submitting request, i.e.
 final voidsetSessionForm(boolean sessionForm)
          Activate resp.

Methods inherited from class org.springframework.web.servlet.mvc.BaseCommandController
setCommandClass, setCommandName, setValidateOnBinding, setValidator

Methods inherited from class org.springframework.web.servlet.mvc.AbstractController
handleRequest, setSynchronizeOnSession

Methods inherited from class org.springframework.web.servlet.support.WebContentGenerator
setCacheSeconds, setRequireSession, setSupportedMethods, setUseCacheControlHeader, setUseExpiresHeader

Methods inherited from class org.springframework.context.support.ApplicationObjectSupport
getApplicationContext, setApplicationContext

Constructor Detail

AbstractFormController

public AbstractFormController()
Create a new AbstractFormController.

Subclasses should set the following properties, either in the constructor or via a BeanFactory: commandName, commandClass, bindOnNewForm, sessionForm. Note that commandClass doesn't need to be set when overriding formBackingObject, as the latter determines the class anyway.

See Also:
BaseCommandController.setCommandName(java.lang.String), BaseCommandController.setCommandClass(java.lang.Class), setBindOnNewForm(boolean), setSessionForm(boolean), formBackingObject(HttpServletRequest)
Method Detail

setBindOnNewForm

public final void setBindOnNewForm(boolean bindOnNewForm)
Set if request parameters should be bound to the form object in case of a non-submitting request, i.e. a new form.

setSessionForm

public final void setSessionForm(boolean sessionForm)
Activate resp. deactivate session form mode. In session form mode, the form is stored in the session to keep the form object instance between requests, instead of creating a new one on each request.

This is necessary for either wizard-style controllers that populate a single form object from multiple pages, or forms that populate a persistent object that needs to be identical to allow for tracking changes.