The problem I am noticing is that when the second action is being invoked, the form is being 'repopulated' with the initial form values that the form had when it was passed to the first action.

Ted Husted

This is an excellent example of what we mean when we talk about "Action chaining", or, as I like to call it, the "dark side of Struts".

There is a very fine design pattern called "Chain of Responsibility" which "Design Patterns"[*] define as "Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it."

Struts does *not* implement a CoR at the Action level. The design is that the Action is the request handler and should do whatever is necessary to complete the transaction, use-case, or story underlying the request.

Since it does not implement a CoR, it does try to populate the ActionForm with every request.

IMHO, the place to implement a Chain of Responsibility is within your Model. If you need anything this complex, you are a candidate for what "Patterns of Enterprise Application Architecture" [*] calls "Domain Objects". You can convert the HTTP request to a business request (of your own devise) and pass it to as many handlers as you see fit.

Personally, I believe implementing a CoR using Struts Actions is a step in the wrong direction. IMHO, we are trying to pull ourselves away from the web tier, not dive back into it =:0)

There are times when one Action should forward to another, but only to display the final result. Using a second action to complete a business transaction is where we start sliding toward the dark side.

But, each to their own.

First, avoid trying to set parameters in the request. Better to set properties on the ActionForm (or other object in the request) that you can control. If the properties are not exposed in the request as parameters, then Struts will ignore them like visitors on a Borg ship.

If you need to tweak ActionForm properties so that they do no match the parameters, in Struts 1.0.x, you can defeat autopopulate by setting up your own "mutable" or "locked" sentry. In each of your setters, put a test like

if (mutable) { ... do the setting }

So if you setMutable(false), then no one can overwrite your maverick data. (Ahh, the magic of JavaBeans!) If one of your actions needs to do some more tweaking, they an unlock the bean and then lock it again.

In Struts 1.1, you could also do clever things with the processPopulate of the RequestHandler.

HTH, Ted.

[*] See the Struts "Other Books" page for links to these and other fine references

HTH, Ted.
Struts in Action

About | Sitemap | Contact