struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Struts Wiki] Update of "StrutsCatalogUsingValidate" by MichaelJouravlev
Date Wed, 20 Apr 2005 08:20:27 GMT
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/StrutsCatalogUsingValidate

New page:
Everyone knows how Struts processes request. Here is a short recap:
   * Form bean is initialized.
   * reset() is called.
   * Fields are populated.
   * validate() is called.
      * if validate() returns non-null object, Struts skips action class altogether, and selects
path corresponding to "input" property.
      * If validate() returns null, then execute() is called on action class.

At first glance seems convenient. If error occurred in the input, then action class is not
bothered at all. But what happens with the user experience? "input" property did not allow
to perform redirect, it allows to forward only. That means, that if a user submitted a form
and made a mistake, the application shows an error page immediately in response to POST request.
That means, that when the user tries to reload the input/error page, he gets "Do you want
to resend POSTDATA?" message generated by browser, which is not nice by itself. And if a user
clicks "Yes", he gets into a double summit situation.

The proper thing to do would be to separate input phase from output phase, and to prevent
these kinds of implicit resubmits. By the way, Ruby On Rails explicitly declare this I/O separation
as their official approach to request processing. Spring can do the same for more than a year.
JSF allows to do this too.

I/O separation is done using redirection:

   * User submits input data using POST
   * Data is validated, the proper view is chosen
   * A user is redirected to the view location
   * A browser loads the view using GET request

Now a user can refresh result page anytime, or browse back and forward without causing resubmit.
He is happy, data is intact, and no tokens needed. Oops, we forgot that "input" property,
which sends a user to the input/error page, does not allow redirection. Thus, this property
cannot be used to redirect a user to error page. Consequently, validate() cannot return errors,
because if error object is not null, control is forwarded (again, forwarded, not redirected)
to error page.

I guess there is a reason for this limited functionality of "input" property. If redirect
were allowed for input/error page, then error messages would have to survive between requests,
thus they would need to be stored somewhere. There are two choices: either to store error
messages on the server, or to stick them into redirect request as query parameters. This functionality
does not exist in Struts at this moment (April 2005, current version is 1.2.6).

So, to provide better user experience and to save yourself from validating tokens, do following:
   * Never return errors from validate() method of a form bean.
   * Stick errors into the session instead, and always return null from validate().
   * After your action class gets control, redirect to input/error page.
   * After redirection, pull errors from the session and stick them into request object.

Here you are, now you have a clean View, and errors are saved.

Because validate() is the last method called on the form bean before calling action class,
the validation functionality can be done in the action class. So, for simplicity sake, do
not use validate() at all, forget that this method exists. This is Nature's mistake.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Mime
View raw message