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/DataEntryForm

------------------------------------------------------------------------------
  #format wiki
  #language en
  
- Data entry form is the most common use case for any interactive application. 
If entered data is correct, application accepts is and often shows a success 
message. Otherwise, application redisplays the data entry form along with 
relevant error messages, operator fixes the errors and submits the form again. 
In this use case a user is able to fill out the form in several attempts, while 
the form preserves data entered by the user on each attempt.
+ Data entry form is the common use case in an interactive application. 
Application displayes a data entry form and collects user input. If entered 
data is correct, application accepts is and displays a success message. 
Otherwise, application redisplays the data entry form along with relevant 
errors, the user fixes the errors and submits the form again. 
+ 
+ In this use case a user is allowed to fill out the form in several attempts, 
while the form preserves data entered by the user on previous attempts.
  
  Struts framework is built around the Front Controller pattern. This pattern 
gives no guidelines on how consecutive requests should interact with each other 
and with business object, neither it specifies how the application should 
manage view state and state of the business object.
  
@@ -11, +13 @@

  
  == Setup/submit pattern ==
  
- An interactive web application can operate in two phases. On ''render phase'' 
(or output phase) browser requests a web resource from the server, and web 
resource displays a page matching its state. On ''accept phase'' (or submit 
phase) browser sends user input to a web resource, usually by submitting an 
HTML form. 
+ An interactive web application operates in two phases. On ''render phase'' 
(or output phase) browser requests a web resource to render itself. On ''accept 
phase'' (or submit phase) browser sends input data to a web resource, usually 
by submitting an HTML form. 
  
- Struts exploits this idea utilizing ''setup/submit pattern'' and two types of 
actions: 
+ Struts implements this two-phase request/response approach utilizing 
''setup/submit pattern'' and two types of actions: 
-  * ''setup action'' (pre-action, output action, render action) is used to 
prepare output data before displaying a JSP page;
+  * ''setup action'' (pre-action, output action, render action) prepares 
output data before displaying a JSP page;
-  * ''submit action'' (post-action, input action, accept action) is used to 
accept user input.
+  * ''submit action'' (post-action, input action, accept action) accepts user 
input.
  
  Setup/submit action pattern is a standard practice for building interactive 
application with Struts.
  
@@ -23, +25 @@

  
  inline:setup_submit_01.gif
  
- Setup action loads data from database and queue it into one or more arbitrary 
objects located in the request or session scope. Submit action processes input 
data and redisplays the same data entry form if errors has been found in the 
input. If input does not contain errors, submit action accepts it and forwards 
to a success page. 
+ Setup action loads data from database and queues it into one or more 
arbitrary objects located in the request or session scope. Submit action 
processes input data and redisplays the same data entry form if errors has been 
found in the input. If input does not contain errors, submit action forwards to 
a success page. 
  
- This approach is far from perfect:
+ This approach is not perfect:
-  * classic setup/submit pattern is focused on a JSP page, not on a web 
resource in general.
+  * Classic setup/submit pattern is focused on a JSP page, not on a web 
resource in general. 
-  * Every page of a web resource is likely to have its own pair of setup and 
submit actions.
+  * Every page of a web resource is likely to have its own pair of setup and 
submit actions. The picture above represents one JSP page and two actions 
associated with it. More pages, more actions, and things can quickly get out of 
control.
   * One web resource is defined with several action mappings in the 
{{{struts-config.xml}}} file as well as with several Java classes.
   * Output data is scattered in an uncontrolled manner throughout request and 
session scope.
   * In case of error the data entry form is redisplayed by a submit action; 
that opens a whole can of worms:
@@ -45, +47 @@

   * Setup action populates !ActionForm and its nested properties with business 
data and forwards to a JSP page.
   * JSP page displays a data entry form filled in with information from the 
!ActionForm.
   * When HTML form is submitted, the !ActionForm is populated automatically by 
Struts with values from the request.
-  * If input is invalid, data entry form is redisplayed; it will have 
contained data submitted by a user on a previous step.
+  * If input is invalid, data entry form is redisplayed; it will contain data 
submitted by a user on a previous step.
  
- Therefore, instead of queueing output data to arbitrary objects in request or 
session scope, a setup action has to use an !ActionForm as the holder of 
input/output data. Mappings of both setup action and submit action would refer 
to the same !ActionForm in their "name" attribute.
+ Therefore, instead of queueing output data to arbitrary objects in request or 
session scope, a setup action fills out an !ActionForm as the holder of 
input/output data. Mappings of both setup action and submit action would refer 
to the same !ActionForm in their "name" attribute.
  
  inline:setup_submit_02.gif
  
- Shared !ActionForm makes it easy to preserve incremental changes made by a 
user in a data entry form.
+ Shared !ActionForm makes it easy to preserve incremental changes made by a 
user in a data entry form and ensures, that all data related to a particular 
web resourse, is neatly stored in one place.
  
  == Step 2: Do not forward to a page that does not belong to current web 
resource ==
  
@@ -69, +71 @@

  
  == Step 4: Reload setup action to redisplay a page ==
  
- Autovalidation is used together with "input" attribute of action mapping in 
struts-config.xml file. If !ActionForm.valiadate returns non-empty error object 
during autovalidation, Struts forwards to location defined in the "input" 
attribute. Usually, it is the same data entry form that was just submitted. 
Therefore, the same form can be represented in the browser with two different 
URLs: one URL when it is rendered by a setup action, and another URL when it is 
redisplayed by a submit action. In most cases the browser is forwarded to the 
page, not redirected, so an attempt to refresh a page after it has been 
redisplayed causes double submit. 
+ Autovalidation is used together with "input" attribute of action mapping in 
{{{struts-config.xml}}} file. If {{{ActionForm.validate}}} returns non-empty 
error object during autovalidation, Struts forwards to location defined in the 
"input" attribute. Usually, it is the same data entry form that was just 
submitted. Therefore, the same form can be represented in the browser with two 
different URLs: one URL when it is rendered by a setup action, and another URL 
when it is redisplayed by a submit action. In most cases browser is forwarded 
to the page, not redirected, so an attempt to refresh a page after it has been 
redisplayed causes double submit. 
  
  These are techniques worth considering when you need to redisplay data entry 
form:
   * Forward to data entry page from submit action, use Struts token feature to 
catch the resubmit. This approach does not protect a user from an unfriendly 
POSTDATA message and it does not help with two URLs situation. Use this 
approach if your !ActionForm is request-scoped and you want to reuse data 
entered by a user.
@@ -77, +79 @@

   * Redirect to a setup action (not directly to a page) appending a business 
object ID and another relevant information to the target URL. This approach 
eliminates resubmit on page refresh, and it solves dual URLs issue. Use this 
option if you want to provide the better and cleaner user experience but you 
don't want to use session-scoped !ActionForms. Your setup action must be able 
to initialize the !ActionForm using ID and another request parameters that you 
have sent in redirected request. If your data entry form is quite large, 
sending all information in a redirected request may not be feasible.
   * Redirect to a setup action (not directly to a page), keeping data entered 
by a user in a session-scoped !ActionForm. This approach is user-friendly, it  
eliminates resubmit on page refresh, solves dual URLs issue and provides a 
clean redirected URL. The only downside of it is keeping !ActionForm in the 
session between requests; this may not be desirable for some applications.
  
- These techniques (except the first one) can be commonly called as ''action 
reloading'', because a page is redisplayed using the same approach, as for 
initial display. Using redirection instead of forwarding protects from implicit 
double submit and hides the submit URL from the browser and from the user. This 
way a page is visible and accessible only from one URL, the setup (render) URL.
+ These techniques (except the first one) can be commonly called as ''action 
reloading'', because a page is redisplayed using the same setup action that was 
used for for initial page display. Using redirection instead of forwarding 
protects from implicit double submit and hides the submit URL from the browser 
and from the user. This way a page is visible and accessible only with setup 
(render) URL.
  
  inline:setup_submit_04.gif
  
@@ -87, +89 @@

  
  == Step 6: Consolidate your actions; use DispatchAction flavor for submit 
action ==
  
- A simple web resource like Customer can have couple of setup action mappings 
like viewCustomer.do and editCustomer.do and several submit action mappings 
like addCustomer.do, updateCustomer.do and deleteCustomer.do.  Of course, this 
does not mean that you need to define five corresponding Java classes. It would 
be great if you could reduce number of action classes down to two: one setup 
action and one submit action per web resource. It would be also great to reduce 
number of action mappings in struts-config.xml file.
+ A simple web resource like {{{Customer}}} can have couple of setup action 
mappings like {{{viewCustomer.do}}} and {{{editCustomer.do}}} and several 
submit action mappings like {{{addCustomer.do}}}, {{{updateCustomer.do}}} and 
{{{deleteCustomer.do}}}.  Of course, this does not mean that you need to define 
five corresponding Java classes. It would be great if you could reduce number 
of action classes down to two: one setup action and one submit action per web 
resource. It would be also great to reduce number of action mappings in 
struts-config.xml file.
  
  First, let us deal with setup actions. You can combine two aforementioned 
mappings into one setupCustomer.do and to differentiate between edit and view 
modes using a request parameter, like setupCustomer.do?mode=edit . Whether to 
use this approach or not depends on your idea of "clean URLs" and other factors.
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to