Struts Dialogs: DialogAction
DialogAction is an abstract Action, which is used as a web resource "code-behind" class.
It is based on SelectAction
and adds the following functionality:
- handles initialization event;
- buffers error messages;
- renders view corresponding to resource state;
- stores state (in an action form);
- separates input and output processes (using POST-redirect-GET pattern)
DialogAction allows to create robust user inteface, which can handle Refresh,
Back and Forward buttons in user-friendly manner, and does not cause double submit
issues or annoying POSTDATA messages.
Two-phase input processing
The most important concept of DialogAction is separation of input and output processes
into two phases. The two-phase approach solves several issues, related to submission of
HTML forms, like double submit problem, annoying POSTDATA messages and
unfriendly user experience for Reload, Back and Forward buttons.
DialogAction has three different modes of operation:
- it sets up web resourse when it receives initialization event;
- it accepts input data, updates domain model and generates error messages on input phase
- it generates a result page during render phase.
HTTP specification recommends to use POST method to modify server data,
while GET method should be used for requests with no side effects. Two-phase request processing
nicely corresponds to HTTP specifications, separating input and output phases by request method:
- browser submits input data using POST request;
- DialogAction accepts input and redirects browser to the location of result page;
- browser loads result page using GET request.
Because this pattern includes redirection, it can also be called as
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 phases,
which are completely independent from server standpoint.
Separation of input and output improves usability and user experience:
- Any page can be reloaded without sending POST request to the server again.
- As a consequence, an application does not have to cope with implicit double submits.
- Another great usability consequence is that a user does not see "Do you want to resend POSTDATA?"
- Using Back and Forward buttons is safe, because only result pages are redisplayed. This behavior
is defined in HTTP specification, which states that a browser must "forget" the POST request
that preceds redirection response.
When an action is loaded either with hyperlink or by typing its location in the browser address
field, browser sends GET request to the server. When DialogAction receives GET request, which does
not contain event parameter, it renders a page. In case of simple dialogs, this would be default view.
In case of multi-page resource this would be a page, corresponding to current resource state.
The page usually contains HTML form, which accepts user data.
When form is submitted, DialogAction dispatches browser event to a corresponding handler method.
To make this happen, automatic validation must be turned off in a corresponding form bean.
The hander should validate input data explicitly, and perform model update if needed.
In case of error, the handler saves errors in the session and redirects to
the same action. This is called resource reloading. It does not cause infinite loop,
because request for data submission has POST type, while redirected request for action
reloading is automatically converted to GET type. GET request does not cause reloading.
Instead, when DialogAction receives GET request, it renders a view, corresponding to current
state. The lifecycle repeats until the resource decides to hand control over to another
resource, usually when user input does not contain errors.
<forward name = "DIALOG-RELOAD" path="/dialogloginaction.do" redirect="true"/>
<forward name = "DIALOG-VIEW" path="/dialogloginaction.jsp"/>
If no errors were detected and action can render a view for new resource state,
then resource can hand control over to another action. Redirection
is a preferred way to hand over the control to prevent double submit issues.
DialogAction has default mapping name, used for resource reloading: "DIALOG-RELOAD".
When a user refreshes a page, DialogAction reloads itself, and displays a view appropriate to
its state. This implies that application state must be stored on server between requests.
The view is rendered by getView method. For a simple web dialog, which has only one
view, the default implementation of getView is sufficient. All you need is define a name of
JSP page in the struts-config.xml file, which corresponds to default "DIALOG-VIEW"
mapping. See example above.
Do not use redirection for a view. If you create more complex web resource
with several views, you need to override getView method and return a proper
mapping for each resource state.
DialogAction has an option to reset the resource when it receives new portion
of data submitted with POST request. POST request method signals that browser submits new
data instead of loading existing information. But sometimes resource has to be reset with
GET method, if it is navigated using hyperlink. DialogAction needs to distinguish these
- reset resource and fill it with new data;
- navigate to resource using a "clean" link;
- refresh a resource explicitly;
- automatically reload a resource as the second phase of input processing.
DialogAction uses event parameter as flag for resource that it can be reset.
Three other situations: "clean" linking, refreshing and resource reloading are
treated the same, because request does not contain event parameter in all three cases. In these
cases DialogAction renders a view, corresponding to current resource state.
In plain words the above means that navigating to a resource via link, which does not
have event key as query parameter, displays current state of resource but does not initialize
it. See live demos for details, and pay attention to resource URLs.
- Make sure that you turned "validate" property off in your action mapping in struts-config.xml file.
Errors must be processed explicitly in the action class.
- Make sure that your action form uses session scope to retain form values between requests. If you are
strongly against storing application state in the session, Struts Dialogs library will not
The following examples show how DialogAction can be used: