java.lang.Objectorg.apache.struts.action.Action
org.apache.struts.actions.DispatchAction
net.jspcontrols.dialogs.actions.SelectAction
net.jspcontrols.dialogs.actions.DialogAction
An abstract Action that provides basic dialog functions, like accepting input data, dispatching submit event to a method, generating and storing error messages and rendering a view. DialogAction allows to create robust user inteface and provides simple event-based programming accounts.
DialogAction incorporates several innovative design decisions not previously used in Struts. Some of them are already implemented in other frameworks, like Ruby on Rails or JSF. Other features are unique to DialogAction.
Input/Output Separation
The cornerstone concept of DialogAction is separation of input and output processes. It solves several issues, related to HTML form input, like double submit problem, annoying POSTDATA messages, bad usability when Reload, Back and Forward buttons are used.
DialogAction defines three different modes of operation:
HTTP specification recommends to use POST request method for server state modification, and GET method for requests with no side effects. Therefore, input and output processes in DialogAction are cleanly separated by request method:
It must be understood, that redirection is an inherent part of this pattern. Redirection allows to split one solid "POST input data, respond with result page" process into two processes, which are completely independent from server standpoint.
Separation of input and output improves usability and user experience:
Event Handlers and View Renderer
Event handlers have the same signature, as execute method, and process POST events, usually from submit buttons of HTML form. An initialization event is one exception from this rule, and can be processed as either POST or GET request. Initialization event has a default key, DIALOG-EVENT.
After input event is processed, DialogAction redirects to itself and
receives GET request from a browser. The same GET request is sent by
the browser when a user reloads a page. In both cases, GET request
is processed by getView
method, which renders an output page.
"Rendering" is probably a too strong word to what getView
method actually does. It simply chooses a mapping name of a JSP page
corresponding to current dialog state, and returns this mapping to Struts
in the same fashion as a regular action.
If a dialog action has only one page to render, then default
getView
implementation, which returns DIALOG-EVENT-VIEW key,
is sufficient. The only thing you need to do is to define
a forward
element in the struts-config.xml file,
which maps view key to a JSP page.
If a dialog action can render different pages depending on application
state, it is called a web control. In this case getView
method should be overriden, and a proper mapping should be returned.
Default keys and mappings
DialogAction uses several predefined keys and mappings, to correlate HTML buttons to handler methods, and to select result pages. These mappings are defined in DialogConstants class:
String DIALOG-VIEW-KEY = "DIALOG-VIEW";
This is a default view mapping, mandatory if a dialog action has only
one page to render. If dialog can render different pages depending
on application state, use action-specific mappings.
String DIALOG-RELOAD-KEY = "DIALOG-RELOAD";
This is a default reload mapping, optional. Can be omitted if
a dialog action redirects to itself for view processing, which is
a default behavior. It is possible to split input and output
processing between two separate actions, in this case use this mapping
to set the "view action" name.
String DIALOG-EVENT-KEY = "DIALOG-EVENT";
This is a default prefix for dialog events.
String DIALOG-EVENT = "DIALOG-EVENT";
This is a default name of initialization parameter.
Usage
DialogAction is supposed to be used for HTML forms, which are submitted using POST request method. When the form is submitted, DialogAction dispatches submit event to a handler method. For this to happed, automatic validation must be turned off. The hander should validate input data explicitly, and perform accounts update.
In case of error, the handler should save errors in the session and redirect to the same action, this is called action reloading. Would not this cause infinite loop? No, because request for data submission has POST type, while redirected request for action reloading has GET type. DialogAction processes requests differently, depending on their type. Action reloading can be performed automatically, see the example.
If no errors detected, control is usually handed over to another action. Redirection is a preferred way to hand over the control to prevent double submit issues.
When a user refreshes a page, action treats the request in the same way as for action reloading, and displays an appropriate view with current form bean values. This implies that application state must be stored on server with session or higher scope.
A special initializing request parameter must be used to initialize
and reset
Notes
validate
method of action form.
SelectAction
,
DialogConstants
Field Summary |
Fields inherited from class net.jspcontrols.dialogs.actions.SelectAction |
keyMethodMap |
Fields inherited from class org.apache.struts.actions.DispatchAction |
clazz, log, messages, methods, types |
Fields inherited from class org.apache.struts.action.Action |
defaultLocale, servlet |
Constructor Summary | |
DialogAction()
|
Method Summary | |
void |
clearMessages(javax.servlet.http.HttpServletRequest request)
Cleans messages stored in the session. |
org.apache.struts.action.ActionForward |
execute(org.apache.struts.action.ActionMapping mapping,
org.apache.struts.action.ActionForm form,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Process the specified HTTP request, and create the corresponding HTTP response (or forward to another web component that will create it). |
org.apache.struts.action.ActionForward |
execute(IDialogAction action,
org.apache.struts.action.ActionMapping mapping,
org.apache.struts.action.ActionForm form,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Process the specified HTTP request, and create the corresponding HTTP response (or forward to another web component that will create it). |
protected java.lang.String |
getActionSuffix()
Returns suffix, used for action mapping. |
org.apache.struts.action.ActionForward |
getDialogView(org.apache.struts.action.ActionMapping mapping,
org.apache.struts.action.ActionForm form,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Returns an ActionForward instance describing the View
for current dialog state, usually a forward to a JSP page. |
protected java.util.Map |
getKeyMethodMap()
Provides mapping between event names (keys) and handler methods (values). |
protected java.lang.String |
getMethodName(org.apache.struts.action.ActionMapping mapping,
org.apache.struts.action.ActionForm form,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
java.lang.String parameter)
Returns the method name, given a prefix and a request object. |
boolean |
isBogusGET(javax.servlet.http.HttpServletRequest request)
Returns true, if GET request contains session ID both in cookie and in the URL itself. |
boolean |
isInit(javax.servlet.http.HttpServletRequest request)
Returns true if request is considered "init" request. |
boolean |
isInput(javax.servlet.http.HttpServletRequest request)
Returns true if request is considered "input" request. |
void |
saveDialogErrors(javax.servlet.http.HttpSession session,
org.apache.struts.action.ActionMessages errors)
Saves dialog errors in the session under Globals.ERROR_KEY key. |
void |
setNoCache(javax.servlet.http.HttpServletResponse response)
Marks response as non-cachable. |
Methods inherited from class net.jspcontrols.dialogs.actions.SelectAction |
buildLookupMap, cancelled, execute, getCancelKey, getDefaultKey, getInitKey, getMethod, resolveEvents, unspecified |
Methods inherited from class org.apache.struts.actions.DispatchAction |
dispatchMethod, getMethod |
Methods inherited from class org.apache.struts.action.Action |
addErrors, addMessages, execute, generateToken, getDataSource, getDataSource, getErrors, getLocale, getMessages, getResources, getResources, getServlet, isCancelled, isTokenValid, isTokenValid, resetToken, saveErrors, saveErrors, saveErrors, saveMessages, saveMessages, saveToken, setLocale, setServlet |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Methods inherited from interface net.jspcontrols.dialogs.actions.ISelectAction |
cancelled, unspecified |
Constructor Detail |
public DialogAction()
Method Detail |
public void clearMessages(javax.servlet.http.HttpServletRequest request)
request
- the HTTP request we are processingpublic void saveDialogErrors(javax.servlet.http.HttpSession session, org.apache.struts.action.ActionMessages errors)
session
- HttpSession objecterrors
- error messages, accumulated while processing inputpublic void setNoCache(javax.servlet.http.HttpServletResponse response)
response
- The HTTP response we are creatingprotected java.lang.String getActionSuffix()
public boolean isInput(javax.servlet.http.HttpServletRequest request)
request
- The HTTP request we are processingpublic boolean isInit(javax.servlet.http.HttpServletRequest request)
Initialization parameter must be defined in a concrete subclass.
request
- The HTTP request we are processingpublic boolean isBogusGET(javax.servlet.http.HttpServletRequest request)
DialogAction tries to keep GET requests clean to encourage browser to keep its page history from growing. When DialogAction detects bogus request, it redirects to itself to ensure clean URL. This time it will be clean, because session ID will be contained in cookie only.
request
- The HTTP request we are processingprotected java.lang.String getMethodName(org.apache.struts.action.ActionMapping mapping, org.apache.struts.action.ActionForm form, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.String parameter) throws java.lang.Exception
getMethodName
in class SelectAction
mapping
- The ActionMapping used to select this instanceform
- The optional ActionForm bean for this request (if any)request
- The HTTP request we are processingresponse
- The HTTP response we are creatingparameter
- The ActionMapping
parameter's name
Contains prefix of submit button names, or several prefixes
separated by comma or semicolon.
java.lang.Exception
protected java.util.Map getKeyMethodMap()
In other words, define the event-to-method mapping either in struts-config.xml file, or in the code using getKeyMethodMap method.
getKeyMethodMap
in class SelectAction
public org.apache.struts.action.ActionForward execute(org.apache.struts.action.ActionMapping mapping, org.apache.struts.action.ActionForm form, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.lang.Exception
ActionForward
instance describing where and how
control should be forwarded, or null
if the response has
already been completed.
execute
in class SelectAction
mapping
- The ActionMapping used to select this instanceform
- The optional ActionForm bean for this request (if any)request
- The HTTP request we are processingresponse
- The HTTP response we are creating
java.lang.Exception
- if an exception occurspublic org.apache.struts.action.ActionForward execute(IDialogAction action, org.apache.struts.action.ActionMapping mapping, org.apache.struts.action.ActionForm form, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.lang.Exception
ActionForward
instance describing where and how
control should be forwarded, or null
if the response has
already been completed.
mapping
- The ActionMapping used to select this instanceform
- The optional ActionForm bean for this request (if any)request
- The HTTP request we are processingresponse
- The HTTP response we are creating
java.lang.Exception
- if an exception occurspublic org.apache.struts.action.ActionForward getDialogView(org.apache.struts.action.ActionMapping mapping, org.apache.struts.action.ActionForm form, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.lang.Exception
ActionForward
instance describing the View
for current dialog state, usually a forward to a JSP page.
If you want to use the default implementation, define the View under "DIALOG-VIEW" name in <forward> element of your action mapping.
To use different mapping name, define the view in <forward> element of your action mapping, and override this method to return ActionForward object for your mapping name.
getDialogView
in interface IDialogAction
mapping
- The ActionMapping used to select this instanceform
- The optional ActionForm bean for this request (if any)request
- The HTTP request we are processingresponse
- The HTTP response we are creating
java.lang.Exception
- if an exception occurs