java.lang.Objectorg.springframework.webflow.action.AbstractAction
org.springframework.webflow.action.MultiAction
org.springframework.webflow.action.FormAction
All Implemented Interfaces:
org.springframework.beans.factory.InitializingBean, Action, org.springframework.beans.factory.InitializingBean
Several action execution methods are provided:
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:
Here is an example implementation of such a form flow:
<view-state id="displayCriteria"> <on-render> <evaluate expression="formAction.setupForm"/> </on-render> <transition on="search" to="executeSearch"> <evaluate expression="formAction.bindAndValidate"/> </transition> </view-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:
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"> <on-render> <evaluate expression="formAction.setupForm"/> <evaluate expression="formAction.setupReferenceData"/> </on-render> ... </view-state>This style of calling multiple action methods in a chain (Chain of Responsibility) is preferred to overriding a single action method. In general, action method overriding is discouraged.
When it comes to validating submitted input data using a registered org.springframework.validation.Validator , this class offers the following options:
public void ${validateMethodName}(${formObjectClass}, Errors)
For instance, having a action definition like this:
<evaluate expression="formAction.bindAndValidate"> <attribute name="validatorMethod" value="validateSearchCriteria"/> </evaluate>Would result in the public void validateSearchCriteria(SearchCriteria, Errors) method of the registered validator being called if the form object class would be
SearchCriteria.
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. |
Erwin - VervaetKeith - Donald| Field Summary | ||
|---|---|---|
| public static final String | DEFAULT_FORM_OBJECT_NAME | The default form object name ("formObject"). |
| public static final 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 org.springframework.webflow.action.AbstractAction: |
|---|
| logger |
| Constructor: |
|---|
|
|
| Method from org.springframework.webflow.action.FormAction Summary: |
|---|
| bind, bindAndValidate, createBinder, createFormObject, doBind, doValidate, getFormErrors, getFormErrorsScope, getFormObject, getFormObjectAccessor, getFormObjectClass, getFormObjectName, getFormObjectScope, getMessageCodesResolver, getPropertyEditorRegistrar, getValidateMethodInvoker, getValidator, initAction, initBinder, registerPropertyEditors, registerPropertyEditors, resetForm, setFormErrorsScope, setFormObjectClass, setFormObjectName, setFormObjectScope, setMessageCodesResolver, setPropertyEditorRegistrar, setValidator, setupForm, toString, validate, validationEnabled |
| Methods from org.springframework.webflow.action.MultiAction: |
|---|
| doExecute, getMethodResolver, setMethodResolver, setTarget |
| Methods from org.springframework.webflow.action.AbstractAction: |
|---|
| afterPropertiesSet, doExecute, doPostExecute, doPreExecute, error, error, execute, getActionNameForLogging, getEventFactorySupport, initAction, no, result, result, result, result, success, success, yes |
| Methods from java.lang.Object: |
|---|
| equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Method from org.springframework.webflow.action.FormAction Detail: |
|---|
NOTE: This action method is not designed to be overridden and might become |
NOTE: This action method is not designed to be overridden and might become |
Default implementation creates a standard WebDataBinder, and invokes #initBinder(RequestContext, DataBinder) and #registerPropertyEditors(PropertyEditorRegistry) . |
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. |
|
validate() method is invoked. |
Keep in mind that an Errors instance wraps a form object, so a form object will also be created if required (see #getFormObject(RequestContext) ). |
|
The returned form object will become the current form 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. |
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. |
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 parameter. |
NOTE: This action method is not designed to be overridden and might become |
|
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) . |
|
|
Default is null, i.e. using the default strategy of the data binder. |
|
|
A new form object instance will only be created (or more generally acquired) with a call to #createFormObject(RequestContext) , if the form object does not yet exist in the configured scope . If you want to reset the form handling machinery, including creation or loading of a fresh form object instance, call #resetForm(RequestContext) instead.
NOTE: This action method is not designed to be overridden and might become |
|
NOTE: This action method is not designed to be overridden and might become |
|