|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectorg.springframework.webflow.action.AbstractAction
org.springframework.webflow.action.MultiAction
org.springframework.webflow.action.FormAction
public class FormAction
Multi-action that implements common logic dealing with input forms. This class leverages the Spring Web data binding code to do binding and validation.
Several action execution methods are provided:
setupForm(RequestContext) - Prepares the form object for
display on a form, creating it and
an associated errors object if necessary, then caching them in
the configured form object scope and
form errors scope, respectively. Also
installs any custom
property editors for formatting form object field values. This action method
will return the "success" event unless an exception is thrown. bindAndValidate(RequestContext) - Binds all incoming request
parameters to the form object and then validates the form object using a
registered validator. This action method
will return the "success" event if there are no binding or validation errors,
otherwise it will return the "error" event. bind(RequestContext) - Binds all incoming request parameters to
the form object. No additional validation is performed. This action method
will return the "success" event if there are no binding errors, otherwise it
will return the "error" event. validate(RequestContext) - Validates the form object using a
registered validator. No data binding is performed. This action method will
return the "success" event if there are no validation errors, otherwise it
will return the "error" event. resetForm(RequestContext) - Resets the form by reloading the
backing form object and reinstalling any custom property editors. Returns
"success" on completion, an exception is thrown when a failure occurs. Since this is a multi-action a subclass could add any number of additional action execution methods, e.g. "setupReferenceData(RequestContext)", or "processSubmit(RequestContext)".
Using this action, it becomes very easy to implement form preparation and submission logic in your flow. One way to do this follows:
setupForm to prepare the new
form for display. bindAndValidate to bind incoming
request parameters to the form object and validate the form object. Here is an example implementation of such a compact form flow:
<view-state id="displayCriteria" view="searchCriteria">
<render-actions>
<action bean="formAction" method="setupForm"/>
</render-actions>
<transition on="search" to="executeSearch">
<action bean="formAction" method="bindAndValidate"/>
</transition>
</view-state>
<action-state id="executeSearch">
<action bean="formAction" method="executeSearch"/>
<transition on="success" to="displayResults"/>
</action-state>
When you need additional flexibility consider splitting the view state above acting as a single logical form state into multiple states. For example, you could have one action state handle form setup, a view state trigger form display, another action state handle data binding and validation, and another process form submission. This would be a bit more verbose but would also give you more control over how you respond to specific results of fine-grained actions that occur within the flow.
Subclassing hooks:
createFormObject. You may override
this to customize where the backing form object instance comes from (e.g
instantiated transiently in memory or loaded from a database).initBinder. This is called
after a new data binder is created.
registerPropertyEditors(PropertyEditorRegistry). By overriding it
you can register any required property editors for your form. Instead of
overriding this method, consider setting an explicit
PropertyEditorRegistrar strategy as a more
reusable way to encapsulate custom PropertyEditor installation logic.validationEnabled(RequestContext) to dynamically
decide whether or not to do validation based on data available in the request
context.
Note that this action does not provide a referenceData() hook method
similar to that of Spring MVC's SimpleFormController. If you
wish to expose reference data to populate form drop downs you can define a
custom action method in your FormAction subclass that does just that. Simply
invoke it as either a chained action as part of the setupForm state, or as a
fine grained state definition itself.
For example, you might create this method in your subclass:
public Event setupReferenceData(RequestContext context) throws Exception {
MutableAttributeMap requestScope = context.getRequestScope();
requestScope.put("refData", lookupService.getSupportingFormData());
return success();
}
... and then invoke it like this:
<view-state id="displayCriteria" view="searchCriteria">
<render-actions>
<action bean="searchFormAction" method="setupForm"/>
<action bean="searchFormAction" method="setupReferenceData"/>
</render-actions>
...
</view-state>
This style of calling multiple action methods in a chain (Chain of
Responsibility) is preferred to overridding a single action method. In
general, action method overriding is discouraged.
When it comes to validating submitted input data using a registered
Validator, this class offers the
following options:
bind(RequestContext) instead of
bindAndValidate(RequestContext) or don't register a validator.bindAndValidate(RequestContext) or validate(RequestContext)
and specify a validatorMethod action
execution attribute. This will invoke the identified custom validator method
on the validator. The validator method signature should follow the following
pattern:
public void ${validateMethodName}(${formObjectClass}, Errors)
For instance, having a action definition like this:
<action bean="searchFormAction" method="bindAndValidate">
<attribute name="validatorMethod" value="validateSearchCriteria"/>
</action>
Would result in the
public void validateSearchCriteria(SearchCriteria, Errors) method
of the registered validator being called if the form object class would be
SearchCriteria.validate
method of the registered validator, call
bindAndValidate(RequestContext) or validate(RequestContext)
without specifying a "validatorMethod" action execution attribute.
FormAction configurable properties
| name | default | description |
| formObjectName | formObject | The name of the form object. The form object will be set in the configured scope using this name. |
| formObjectClass | null | The form object class for this action. An instance of this class will get populated and validated. Required when using a validator. |
| formObjectScope | flow |
The scope in which the form object will be put. If put in flow scope the object will be cached and reused over the life of the flow, preserving previous values. Request scope will cause a new fresh form object instance to be created on each request into the flow execution. |
| formErrorsScope | flash |
The scope in which the form object errors instance will be put. If put in flash scope form errors will be cached until the next user event is signaled. |
| propertyEditorRegistrar | null | The strategy used to register custom property editors with the data
binder. This is an alternative to overriding the
registerPropertyEditors(PropertyEditorRegistry) hook method. |
| validator | null | The validator for this action. The validator must support the specified form object class. |
| messageCodesResolver | null | Set the strategy to use for resolving errors into message codes. |
PropertyEditorRegistrar,
DataBinder,
ScopeType| Nested Class Summary |
|---|
| Nested classes/interfaces inherited from class org.springframework.webflow.action.MultiAction |
|---|
MultiAction.MethodResolver |
| Field Summary | |
|---|---|
static java.lang.String |
DEFAULT_FORM_OBJECT_NAME
The default form object name ("formObject"). |
static java.lang.String |
VALIDATOR_METHOD_ATTRIBUTE
Optional attribute that identifies the method that should be invoked on the configured validator instance, to support piecemeal wizard page validation ("validatorMethod"). |
| Fields inherited from class org.springframework.webflow.action.AbstractAction |
|---|
logger |
| Constructor Summary | |
|---|---|
FormAction()
Bean-style default constructor; creates a initially unconfigured FormAction instance relying on default property values. |
|
FormAction(java.lang.Class formObjectClass)
Creates a new form action that manages instance(s) of the specified form object class. |
|
| Method Summary | |
|---|---|
Event |
bind(RequestContext context)
Bind incoming request parameters to allowed fields of the form object. |
Event |
bindAndValidate(RequestContext context)
Bind incoming request parameters to allowed fields of the form object and then validate the bound form object if a validator is configured. |
protected org.springframework.validation.DataBinder |
createBinder(RequestContext context,
java.lang.Object formObject)
Create a new binder instance for the given form object and request context. |
protected java.lang.Object |
createFormObject(RequestContext context)
Create the backing form object instance that should be managed by this form action. |
protected void |
doBind(RequestContext context,
org.springframework.validation.DataBinder binder)
Bind allowed parameters in the external context request parameter map to the form object using given binder. |
protected void |
doValidate(RequestContext context,
java.lang.Object formObject,
org.springframework.validation.Errors errors)
Validate given form object using a registered validator. |
protected org.springframework.validation.Errors |
getFormErrors(RequestContext context)
Convenience method that returns the form object errors for this form action. |
ScopeType |
getFormErrorsScope()
Get the scope in which the Errors object will be placed. |
protected java.lang.Object |
getFormObject(RequestContext context)
Convenience method that returns the form object for this form action. |
protected FormObjectAccessor |
getFormObjectAccessor(RequestContext context)
Factory method that returns a new form object accessor for accessing form objects in the provided request context. |
java.lang.Class |
getFormObjectClass()
Return the form object class for this action. |
java.lang.String |
getFormObjectName()
Return the name of the form object in the configured scope. |
ScopeType |
getFormObjectScope()
Get the scope in which the form object will be placed. |
org.springframework.validation.MessageCodesResolver |
getMessageCodesResolver()
Return the strategy to use for resolving errors into message codes. |
org.springframework.beans.PropertyEditorRegistrar |
getPropertyEditorRegistrar()
Get the property editor registration strategy for this action's data binders. |
protected DispatchMethodInvoker |
getValidateMethodInvoker()
Returns a dispatcher to invoke validation methods. |
org.springframework.validation.Validator |
getValidator()
Returns the validator for this action. |
protected void |
initAction()
Action initializing callback, may be overriden by subclasses to perform custom initialization logic. |
protected void |
initBinder(RequestContext context,
org.springframework.validation.DataBinder binder)
Initialize the new binder instance. |
protected void |
registerPropertyEditors(org.springframework.beans.PropertyEditorRegistry registry)
Register custom editors to perform type conversion on fields of your form object during data binding and form display. |
protected void |
registerPropertyEditors(RequestContext context,
org.springframework.beans.PropertyEditorRegistry registry)
Register custom editors to perform type conversion on fields of your form object during data binding and form display. |
Event |
resetForm(RequestContext context)
Resets the form by clearing out the form object in the specified scope and recreating it. |
void |
setFormErrorsScope(ScopeType errorsScope)
Set the scope in which the Errors object will be placed. |
void |
setFormObjectClass(java.lang.Class formObjectClass)
Set the form object class for this action. |
void |
setFormObjectName(java.lang.String formObjectName)
Set the name of the form object in the configured scope. |
void |
setFormObjectScope(ScopeType scopeType)
Set the scope in which the form object will be placed. |
void |
setMessageCodesResolver(org.springframework.validation.MessageCodesResolver messageCodesResolver)
Set the strategy to use for resolving errors into message codes. |
void |
setPropertyEditorRegistrar(org.springframework.beans.PropertyEditorRegistrar propertyEditorRegistrar)
Set a property editor registration strategy for this action's data binders. |
Event |
setupForm(RequestContext context)
Prepares a form object for display in a new form, creating it and caching it in the getFormObjectScope() if necessary. |
void |
setValidator(org.springframework.validation.Validator validator)
Set the validator for this action. |
Event |
validate(RequestContext context)
Validate the form object by invoking the validator if configured. |
protected boolean |
validationEnabled(RequestContext context)
Return whether validation should be performed given the state of the flow request context. |
| Methods inherited from class org.springframework.webflow.action.MultiAction |
|---|
doExecute, getMethodResolver, setMethodResolver, setTarget |
| Methods inherited from class org.springframework.webflow.action.AbstractAction |
|---|
afterPropertiesSet, doPostExecute, doPreExecute, error, error, execute, getActionNameForLogging, getEventFactorySupport, no, result, result, result, result, success, success, yes |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Methods inherited from interface org.springframework.beans.factory.InitializingBean |
|---|
afterPropertiesSet |
| Field Detail |
|---|
public static final java.lang.String DEFAULT_FORM_OBJECT_NAME
public static final java.lang.String VALIDATOR_METHOD_ATTRIBUTE
| Constructor Detail |
|---|
public FormAction()
formObjectClass property
or override createFormObject(RequestContext).
setFormObjectClass(Class)public FormAction(java.lang.Class formObjectClass)
formObjectClass - the class of the form object (must be instantiable)| Method Detail |
|---|
public java.lang.String getFormObjectName()
public void setFormObjectName(java.lang.String formObjectName)
public java.lang.Class getFormObjectClass()
public void setFormObjectClass(java.lang.Class formObjectClass)
setValidator(Validator))!
If no form object name is set at the moment this method is called, a
form object name will be automatically generated based on the provided
form object class using
ClassUtils.getShortNameAsProperty(java.lang.Class).
public ScopeType getFormObjectScope()
public void setFormObjectScope(ScopeType scopeType)
flow scope.
public ScopeType getFormErrorsScope()
public void setFormErrorsScope(ScopeType errorsScope)
flash scope.
public org.springframework.beans.PropertyEditorRegistrar getPropertyEditorRegistrar()
public void setPropertyEditorRegistrar(org.springframework.beans.PropertyEditorRegistrar propertyEditorRegistrar)
registerPropertyEditors(PropertyEditorRegistry) method.
public org.springframework.validation.Validator getValidator()
public void setValidator(org.springframework.validation.Validator validator)
form object class. The validator
must support the specified form object class.
public org.springframework.validation.MessageCodesResolver getMessageCodesResolver()
public void setMessageCodesResolver(org.springframework.validation.MessageCodesResolver messageCodesResolver)
Default is null, i.e. using the default strategy of the data binder.
createBinder(RequestContext, Object),
DataBinder.setMessageCodesResolver(org.springframework.validation.MessageCodesResolver)protected void initAction()
AbstractAction
Keep in mind that this hook will only be invoked when this action is
deployed in a Spring application context since it uses the Spring
InitializingBean mechanism to trigger action initialisation.
initAction in class AbstractAction
public Event setupForm(RequestContext context)
throws java.lang.Exception
getFormObjectScope() if necessary. Also installs
custom property editors for formatting form object values in UI controls
such as text fields.
NOTE: This is action method is not designed to be overidden and might
become final in a future version of Spring Web Flow. If
you need to execute custom form setup logic have your flow call this
method along with your own custom methods as part of a single action
chain.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"
java.lang.Exception - an unrecoverable exception occurs, either
checked or uncheckedcreateFormObject(RequestContext)
public Event bindAndValidate(RequestContext context)
throws java.lang.Exception
NOTE: This action method is not designed to be overidden and might
become final in a future version of Spring Web Flow. If
you need to execute custom bind and validate logic have your flow call
this method along with your own custom methods as part of a single action
chain. Alternatively, override the
doBind(RequestContext, DataBinder) or
doValidate(RequestContext, Object, Errors) hooks.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"
java.lang.Exception - an unrecoverable exception occured, either
checked or unchecked
public Event bind(RequestContext context)
throws java.lang.Exception
NOTE: This is action method is not designed to be overidden and might
become final in a future version of Spring Web Flow. If
you need to execute custom data binding logic have your flow call this
method along with your own custom methods as part of a single action
chain. Alternatively, override the
doBind(RequestContext, DataBinder) hook.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"
java.lang.Exception - an unrecoverable exception occured, either
checked or unchecked
public Event validate(RequestContext context)
throws java.lang.Exception
NOTE: This is action method is not designed to be overidden and might
become final in a future version of Spring Web Flow. If
you need to execute custom validation logic have your flow call this
method along with your own custom methods as part of a single action
chain. Alternatively, override the
doValidate(RequestContext, Object, Errors) hook.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"
java.lang.Exception - an unrecoverable exception occured, either
checked or uncheckedgetValidator()
public Event resetForm(RequestContext context)
throws java.lang.Exception
NOTE: This is action method is not designed to be overidden and might
become final in a future version of Spring Web Flow. If
you need to execute custom reset logic have your flow call this method
along with your own custom methods as part of a single action chain.
context - the request context
java.lang.Exception - if an exception occuredcreateFormObject(RequestContext)
protected final java.lang.Object getFormObject(RequestContext context)
throws java.lang.Exception
createFormObject(RequestContext) and exposed in the
configured scope.
The returned form object will become the
current
form object.
context - the flow execution request context
java.lang.Exception - when an unrecoverable exception occurs
protected final org.springframework.validation.Errors getFormErrors(RequestContext context)
throws java.lang.Exception
scope.
Keep in mind that an Errors instance wraps a form object, so a form
object will also be created if required
(see getFormObject(RequestContext)).
context - the flow request context
java.lang.Exception - when an unrecoverable exception occurs
protected org.springframework.validation.DataBinder createBinder(RequestContext context,
java.lang.Object formObject)
Default implementation creates a standard WebDataBinder, and invokes
initBinder(RequestContext, DataBinder) and
registerPropertyEditors(PropertyEditorRegistry).
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"formObject - the form object to bind onto
initBinder(RequestContext, DataBinder),
setMessageCodesResolver(MessageCodesResolver)
protected void doBind(RequestContext context,
org.springframework.validation.DataBinder binder)
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"binder - the data binder to use
protected void doValidate(RequestContext context,
java.lang.Object formObject,
org.springframework.validation.Errors errors)
throws java.lang.Exception
validate() method
is invoked.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"formObject - the form objecterrors - the errors instance to record validation errors in
java.lang.Exception - when an unrecoverable exception occursprotected DispatchMethodInvoker getValidateMethodInvoker()
protected FormObjectAccessor getFormObjectAccessor(RequestContext context)
context - the flow request context
protected java.lang.Object createFormObject(RequestContext context)
throws java.lang.Exception
form action. By default, will attempt to instantiate
a new form object instance of type getFormObjectClass()
transiently in memory.
Subclasses should override if they need to load the form object from a specific location or resource such as a database or filesystem.
Subclasses should override if they need to customize how a transient form object is assembled during creation.
context - the action execution context for accessing flow data
java.lang.IllegalStateException - if the getFormObjectClass()
property is not set and this method has not been overridden
java.lang.Exception - when an unrecoverable exception occurs
protected void initBinder(RequestContext context,
org.springframework.validation.DataBinder binder)
allowed fields
and required fields. Called by
createBinder(RequestContext, Object)
Note that registration of custom property editors should be done in
registerPropertyEditors(PropertyEditorRegistry), not here! This
method will only be called when a new data binder is created, e.g. when
data binding needs to be done. In other cases,
e.g. form setup, it will not be
called since no data binder is required.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"binder - new binder instancecreateBinder(RequestContext, Object)
protected void registerPropertyEditors(RequestContext context,
org.springframework.beans.PropertyEditorRegistry registry)
data binder initialization.
Property editors give you full control over how objects are transformed to and from a formatted String form for display on a user interface such as a HTML page.
This default implementation will call the
simpler form of
the method not taking a RequestContext.
context - the action execution context, for accessing and setting
data in "flow scope" or "request scope"registry - the property editor registry to register editors inregisterPropertyEditors(PropertyEditorRegistry)protected void registerPropertyEditors(org.springframework.beans.PropertyEditorRegistry registry)
data binder initialization.
Property editors give you full control over how objects are transformed to and from a formatted String form for display on a user interface such as a HTML page.
This default implementation will simply call registerCustomEditors
on the propertyEditorRegistrar object
that has been set for the action, if any.
registry - the property editor registry to register editors inprotected boolean validationEnabled(RequestContext context)
context - the request context, for accessing and setting data in
"flow scope" or "request scope"
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||