Author(s)Rod Johnson, Juergen Hoeller, Alef Arendsen, Rob Harrop, Colin Sampaleanu
Form controller that auto-populates 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.
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 JavaBeans without having to implement a framework-specific class
(like Struts' 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
a java.beans.PropertyEditor. For more information on that
subject, see the workflow of this controller and the explanation of the
BaseCommandController .
The controller receives a request for a new form (typically a GET).
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 overridden
to e.g. retrieve an object from the database (that needs to be modified
using the form).
Call to initBinder() which allows you to register
custom editors for certain fields (often properties of non-primitive
or non-String types) of the command class. This will render appropriate
Strings for those property values, e.g. locale-specific date strings.
Only if bindOnNewForm is set to true, then
ServletRequestDataBinder
gets applied to populate the new form object with initial request parameters and the
onBindOnNewForm(HttpServletRequest, Object, BindException) callback method is
called. Note: any defined Validators are not applied at this point, to allow
partial binding. However be aware that any Binder customizations applied via
initBinder() (such as
setRequiredFields(String[]) will
still apply. As such, if using bindOnNewForm=true and initBinder() customizations are
used to validate fields instead of using Validators, in the case that only some fields
will be populated for the new form, there will potentially be some bind errors for
missing fields in the errors object. Any view (JSP, etc.) that displays binder errors
needs to be intelligent and for this case take into account whether it is displaying the
initial form view or subsequent post results, skipping error display for the former.
Call to showForm()
to return a View that should be rendered (typically the view that renders
the form). This method has to be implemented in subclasses.
The showForm() implementation will call referenceData() ,
which you can implement to provide any relevant reference data you might need
when editing a form (e.g. a List of Locale objects you're going to let the
user select one from).
Model gets exposed and view gets rendered, to let the user fill in the form.
The controller receives a form submission (typically a POST).
To use a different way of detecting a form submission, override the
isFormSubmission method.
If sessionForm is not set, formBackingObject()
is called to retrieve a form object. Otherwise, the controller tries to
find the command object which is already bound in the session. If it cannot
find the object, it does a call to handleInvalidSubmit
which - by default - tries to create a new form object and resubmit the form.
The ServletRequestDataBinder
gets applied to populate the form object with current request parameters.
Call to onBind(HttpServletRequest, Object, Errors) which allows
you to do custom processing after binding but before validation (e.g. to manually
bind request parameters to bean properties, to be seen by the Validator).
If validateOnBinding is set, a registered Validator will be invoked.
The Validator will check the form object properties, and register corresponding
errors via the given Errors
object.
Call to onBindAndValidate() which allows you
to do custom processing after binding and validation (e.g. to manually
bind request parameters, and to validate them outside a Validator).
Call processFormSubmission() to process the submission, with
or without binding errors. This method has to be implemented in subclasses.
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,
by default trying to resubmit. It can be overridden in subclasses to show
corresponding messages or to redirect to a new form, in order to avoid duplicate
submissions. The form object in the session can be considered a transaction
token in that 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.
Indicates whether to bind servlet request parameters when
creating a new form. Otherwise, the parameters will only be
bound on form submission attempts.
sessionForm
false
Indicates whether the form object should be kept in the session
when a user asks for a new form. This allows you e.g. to retrieve
an object from the database, let the user edit it, and then persist
it again. Otherwise, a new command object will be created for each
request (even when showing the form again after validation errors).
Form controller that auto-populates a form bean from the request. This, either using a new bean instance per request, or using the same bean when the
sessionFormproperty has been set totrue.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
showFormto prepare the form view, andprocessFormSubmissionto 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
Actionshows us that with Spring, you can use any ordinary JavaBeans or database- backed JavaBeans without having to implement a framework-specific class (like Struts'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 ajava.beans.PropertyEditor. For more information on that subject, see the workflow of this controller and the explanation of the BaseCommandController .Workflow (and that defined by superclass):
bindOnNewFormis set totrue, then ServletRequestDataBinder gets applied to populate the new form object with initial request parameters and the onBindOnNewForm(HttpServletRequest, Object, BindException) callback method is called. Note: any defined Validators are not applied at this point, to allow partial binding. However be aware that any Binder customizations applied via initBinder() (such as setRequiredFields(String[]) will still apply. As such, if using bindOnNewForm=true and initBinder() customizations are used to validate fields instead of using Validators, in the case that only some fields will be populated for the new form, there will potentially be some bind errors for missing fields in the errors object. Any view (JSP, etc.) that displays binder errors needs to be intelligent and for this case take into account whether it is displaying the initial form view or subsequent post results, skipping error display for the former.sessionFormis not set, formBackingObject() is called to retrieve a form object. Otherwise, the controller tries to find the command object which is already bound in the session. If it cannot find the object, it does a call to handleInvalidSubmit which - by default - tries to create a new form object and resubmit the form.validateOnBindingis set, a registered Validator will be invoked. The Validator will check the form object properties, and register corresponding errors via the given ErrorsIn 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, by default trying to resubmit. It can be overridden in subclasses to show corresponding messages or to redirect to a new form, in order to avoid duplicate submissions. The form object in the session can be considered a transaction token in that 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):