On Thu, 15 Aug 2002, Joe Cheng wrote:

> Date: Thu, 15 Aug 2002 20:17:06 -0400
> From: Joe Cheng <[EMAIL PROTECTED]>
> Reply-To: Struts Developers List <[EMAIL PROTECTED]>
> To: 'Struts Developers List' <[EMAIL PROTECTED]>
> Subject: RE: concerns about Struts
>
> >>
> In Struts, you make this possible by using String properties in the form
> bean for such fields, and do the conversions later (perhaps in the Action,
> via a call to something like BeanUtils.copyProperties() from the form
> bean into your model bean that does the required conversions -- but you
> know they are going to work).
> <<
>
> Let me make sure I'm understanding you... what you're saying is that you
> want to retain the original, unparsed data for a while, because you may need
> to redisplay it to the user.  And if that wasn't the case--i.e. the form
> bean's setter requires an int, instead of the original String entered by the
> user--you wouldn't be able to use the form bean to repopulate the form.
>

Not only that ... the BeanUtils.populate() call that is copying request
parameters into the form bean will have thrown a conversion exception, and
(because it's walking through a Map of parameters), there's no guarantees
about which properties have been set and which ones have not.

> Once you've validated all the Strings, you can go ahead and copy the form
> bean into the REAL form bean you want to use, which has typed
> getters/setters.
>
> Sound right?
>

There are a couple of different ways to actually do this, but you've got
the basic idea.  One common approach, for example, is to do the transfer
from the form bean directly to a DTO or value object that you're going to
send to your persistence tier.  If the form bean has a String, and the
value object has an int, BeanUtils.copyProperties() will do the conversion
for you.

Another common approach is an attempt to optimize things by performing the
conversion only once, in the validate() method of the form bean.  It goes
something like this for an integer property named foo:

* Define the following methods in your form bean:
    public String getFooString();
    public void setFooString(String fooString);
    public int getFoo();

* In your form, use property name "fooString" so that Struts will
  use the String storage of the property, and not suffer from
  conversion failures.

* In your validate() method, attempt to convert the string version
  of this to an integer.  If conversion succeeds, save the integer
  where getFoo() can get it.  If conversion fails, add an error message
  to the message list.

* In your Action, call getFoo() to get the converted value, or
  use BeanUtils.copyProperties() with a destination bean that
  has a setFoo(int foo) method.

> And you're saying that WebWorks actions are http-agnostic, because they are
> literally just (poorly-encapsulated) objects... you call some setters, then
> execute.
>

Somebody *really* doesn't like the command pattern :-).

> Well, couldn't you just as easily unit-test Struts actions?  Instead of
> calling setters on webwork actions, you're just calling setters on the form
> bean... (though the ActionMapping seems to be pretty HTTP-specific.)
>

Actions take HttpServletRequest and HttpServletResponse as parameters.
They also have indirect access to the owning ActionServlet instance.

You have to fake a bunch of servlet API functionality to test Actions
well.  Two common strategies are mock objects (i.e. the test harness
includes fake ServletContext, HttpRequestSessionn, etc. implementations)
and in-container testing.

Both approaches have value.  I tend to like the former because it's easier
to control the environment, but at the cost of having to write all the
mock objects (and the risk that you'll unknowingly mask bugs because your
mock objects don't act like the "real" container in some respects).  For
people who like the in-container approach, the Cactus project
<http://jakarta.apache.org/cactus> is a good starting point.

Craig


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

Reply via email to