Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Struts Wiki" for change 
notification.

The following page has been changed by MichaelJouravlev:
http://wiki.apache.org/struts/StrutsManualActionClasses

------------------------------------------------------------------------------
  
  One of the reasons of splitting this functionality into two actions is that 
Action class uses just one {{{execute()}}} method to handle all kinds of 
requests. (Servlet has separate {{{doGet()}}} and {{{doPost()}}} methods.)
  
+ inline:setup_submit_improved.gif
+ 
+ inline:icon_alert.gif The above diagram shows the improved Setup/Submit 
Pattern. To see the original Setup/Submit Pattern click here (TODO).
+ 
  A typical Setup Action will often implement the following logic in its 
{{{execute}}} method:
  
   * Make sure that a user is allowed to see the content of a web page that 
corresponds to the action.
@@ -79, +83 @@

  
  A typical Submit Action will often implement the following logic in its 
{{{execute}}} method:
  
-  * Validate the form bean properties as needed. If a problem is found, store 
the appropriate error message keys as a request (or session) attribute, and 
forward (or redirect) control to the input form so that the errors can be 
corrected.
+  * Validate the form bean properties as needed. If a problem is found, store 
the appropriate error message keys as a request (or session) attribute, and 
forward (or redirect) control to the setup action so that the errors can be 
corrected.
   * If input data is valid, perform the business task such as saving a row 
into a database. This can be done by logic code embedded within the Action 
class itself, but should generally be performed by calling an appropriate 
method of a business logic bean.
   * Update the server-side objects that will be used to create the next page 
of the user interface. These objects would typically be request scope or 
session scope beans, depending on how long you need to keep these items. 
-  * Return an appropriate !ActionForward object that identifies the 
presentation page to be used to generate this response, based on the newly 
updated beans. Typically, you will acquire a reference to such an object by 
calling findForward on either the ActionMapping object you received (if you are 
using a logical name local to this mapping), or on the controller servlet 
itself (if you are using a logical name global to the application).
+  * Return an appropriate !ActionForward object that identifies the next web 
resource.
  
  The flip side of Struts flexibility is greater complexity of a most common 
request/response cycle comparing to similar ASP.NET request/response cycle:
  
  inline:asp_render_submit.gif
- 
- Besides the sheer complexity, original Struts setup/submit pattern has other 
design and usability implications:
-  * Most developers program actions as simple services, not as part of a 
logical web resource. Thus one Action often deals with only one message, like 
{{{updateCustomer.do}}} handles "Update Customer" event, 
{{{deleteCustomer.do}}} handles "Delete Customer" event.
-  * Output data is often scattered in an uncontrolled manner throughout 
request and session scope.
-  * In case of error the data entry form is redisplayed by a submit action. 
This means that submit action duplicates setup functionality of setup action.
-  * This pattern often relies to automatic validation. The downside of this 
approach is that in case of error the submit action class is never get called 
and cannot affect the workflow.
-  * One page is represented with two different URLs in the browser.
-  * An attempt to refresh a page after it has been redisplayed causes double 
submit.
-  * Success page where submit action forwards to, often corresponds to a 
logically different resource. It is impossible to tell which logical resource 
is managed by which Action classes. The M:M relationship between actions and 
pages leads to a spaghetti code both in Java code as well as in 
{{{struts-config.xml}}} file.
- 
- inline:icon_alert.gif This chapter discussed the improved Setup/Submit 
Pattern. To see the original Setup/Submit Pattern click here.
- 
- == Improving Setup/Submit Pattern ==
- 
- Use !ActionForm object to store both input and output data. Use the same 
!ActionForm object in both setup and submit actions. Declaratively (via 
{{{struts-config.xml}}}) associate the action form with submit action only, do 
not associate the action form with setup action.
- 
- On setup phase, prepare the action form with output data and forward to a 
view. When a user submits HTML form, Struts will populate the action form that 
is associated with submit action. This is the same form that was used to render 
a page.
- 
- If input data is not valid, do not redisplay the page from submit action. 
Instead, update application state if needed, generate error messages, and 
forward control to setup action. It is the job of setup action to prepare and 
display views; the job of submit action is to handle the input and to update 
application state.
- 
- If action form was associated with setup action, it would be repopulated by 
Struts. Remember, that action form has not been associated with setup action, 
so it will not be repopulated when control is forwarded to setup action from 
submit action. Setup action will render the page along with error messages that 
have been generated by submit action.
- 
- Instead of forwarding to success '''page''', forward to '''setup action''' of 
success web resource.
- 
- The above steps will allow to cleanly separate concerns between actions, as 
well as to keep input/output data in one place.
- 
- inline:setup_submit_improved.gif
  
  == Action As Event Dispatcher ==
  
  Event Dispatcher handles a group of related messages (events, commands). 
These messages often correspond to one business object, like classic Create, 
Retrieve, Update and Delete messages that identify basic operations on 
persistent objects in a database-driven application. Event Dispatcher usually 
changes application state based on incoming message. Application state can be 
stored in a database, a flat file or in a scoped object like !HttpSession or 
!HttpServletRequest.
  
  An event dispatcher has methods that correspond to incoming messages. 
Therefore an Action that manages a persistent object will likely have 
{{{create}}}, {{{retrieve}}}, {{{update}}} and {{{delete}}} methods. Each 
method is triggered with a specific parameter sent in a request.
- 
- inline:event_dispatcher.gif
  
  Struts defines several dispatch classes like !DispatchAction, 
!LookupDispatchAction, !MappingDispatchAction, !EventDispatchAction. These 
subclasses decode an event from incoming request and dispatch it to a 
corresponding event handler. The exact way of defining events depends on 
specific Action subclass. 
  

Reply via email to