Home
Introduction
Tutorial
Demo Application
Test Applicaton
License
Download
Commercial Support
Contributors
Struts-Homepage
The demo application

There is a very trivial demo application included in the source distribution of the Struts Workflow Extension that demonstrates how a wizard-like sequence of dialogs can be implemented. This wizard demo application consists of three screens: The first two screens prompt the user for the first and the second operand. The third screen presents the result, which is just the sum of the two operands the user entered. This is about the simplest wizard-like sequence of dialogs you can think of. Yet it is well-suited to demonstrate, how a wizard can be made bulletproof with the Struts Workflow Extension. For this, three issues need to be tackled: the user must not be able to enter the wizard in the middle, he must not be able to leave it uncontrolled and re-submitting a form must be handled gracefully.

You can live-access the demo application here.

However, it makes much more sense to download the demo application and install it locally in your JSP container, so you can look at the log output, when progressing through it. This is essential to understand what's going on.

This is what the demo application looks like, when you access the index page:

When the link "Start Wizard" is clicked, the first screen of the wizard is displayed:

In this dialog the user is prompted for a valid integer number. If the user decides to click on one of the links "Home" or "Start Wizard" in the side navigation (which is left active for demonstration purposes here, so you can easily simulate unexpected requests), the wizard workflow is violated and the user is brought back to the same screen which then also displays an error message:

The only valid requests are issued, if the user clicks the "Cancel" or "Next" button, the first one terminating the wizard in a well-defined way, the second one allowing the user to progress to the next screen:

In the second screen the user is also trapped, until he uses one of the buttons "Back", "Next" or "Cancel". Hitting the browser's "Reload"-Button which would normally cause a double submit, is also handled gracefully, i. e. a workflow violation is detected and the user is brought back to the same screen.

After the user has finally inserted the second operand, he is forwarded to the third screen, which presents the sum of the two operands as the result.

If the user tries to enter the wizard right in the middle (e. g. by typing in the url "displayWizardScreen2.do") he is brought to the first screen.

The behaviour we are seeing here, that the user is captured in a dialog, is well known from desktop applications that can make use of modal dialogs. In web applications you normally do not have modal dialogs available. Still, this example shows, that it is easily possible to implement them with the Struts Workflow Extension. Having modal dialogs available can make your life very easy, because you can be sure that your action code is only executed after the expected preconditions are true. This relieves you from putting code in your actions that checks these preconditions and it ensures that your sessions stay lean and clean, because you can force the user to progress in a dialog or end it with only a few well-defined actions. This gives you the chance to clean up the session from the data that has been put there, when the dialog was started.

Let's walk through an example: Below is the log output that says what is going on, when the user tries to enter the dialog right in the middle by submitting the second screen without having walked through the first screen before:

Processing a 'POST' for path '/submitWizardScreen2'
No workflows defined
Previous primary workflow: none
Violated prevState condition of workflow: wizardScreen2. Cleaning up and removing this workflow.
Forwarding to "workflowViolation_wizardScreen2": ForwardConfig[name=workflowViolation_wizardScreen2,
    path=/wizardScreen2Violation.do,redirect=false,contextRelative=false]
Processing a 'POST' for path '/wizardScreen2Violation'
No workflows defined
Previous primary workflow: none
Processing a 'POST' for path '/displayWizardScreen2'
No workflows defined
Previous primary workflow: none
Violated prevState condition of workflow: wizardScreen1. Cleaning up and removing this workflow.
Forwarding to "workflowViolation_wizardScreen1": ForwardConfig[name=workflowViolation_wizardScreen1,
    path=/wizardScreen1Violation.do,redirect=false,contextRelative=false]
Processing a 'POST' for path '/wizardScreen1Violation'
No workflows defined
Previous primary workflow: none
Processing a 'POST' for path '/displayWizardScreen1'
No workflows defined
Previous primary workflow: none
Violated prevState condition of workflow: prepareWizard. Cleaning up and removing this workflow.
Forwarding to "workflowViolation_prepareWizard": ForwardConfig[name=workflowViolation_prepareWizard,
    path=/startWizard.do,redirect=false,contextRelative=false]
Processing a 'POST' for path '/startWizard'
No workflows defined
Previous primary workflow: none
Updating workflow: prepareWizard
  Setting currentState to initialized
Processing a 'POST' for path '/displayWizardScreen1'
Defined Workflows: 
  prepareWizard - Current state: initialized, Defined next states: [], Cleanup action names: 
    [AddSessionAttributeCleanup_wizardForm]
Previous primary workflow: prepareWizard
Updating workflow: wizardScreen1
  Setting currentState to displayed
  Setting definedNextStates to [submitted]

The log basically says that the prevState condition of the workflow "wizardScreen2" is violated and therfore forwards to the action "/wizardScreen2Violation", which saves an error message and immediately forwards to "/displayWizardScreen2". This action expects workflow "wizardScreen1" to be in the state "submitted". As this is not true (because the user tried to submit the second screen without having finished the first screen before), a prevState violation of "wizardScreen1" is detected now, which causes a forward to "wizardScreen1Violation" that passes control to "/displayWizardScreen1". This action in turn expects workflow "prepareWizard" to be in the state "initialized", which is not true either, so it forwards to the action "/startWizard". This action does not depend on any other workflows, i. e. it does not define any prevState conditions. Thus, this action can be executed, brings the workflow "prepareWizard" into the state "initialized" and forwards to "/displayWizardScreen1". This time the action can be executed successfully, because now the prevState conditions are true.

We see, that finally the request for submitting the second screen results in the same response, as if the user would have started the wizard normally with the action "/startWizard": The first screen is presented to the user.