This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I have a screen that displays several lines of search results. Each line represents a record in the database. From this screen the user can change the status of a record to "Approved" and press the "save" button to save the change to the database. The screen is then re-displayed and those entries that have had the status changed to "Approved" are no longer displayed.
When the user changes a status and the screen is re-displayed I want to display a message at the top of the screen saying "your update has been successfully processed". To do this I used the method Action.saveMessages(request,actionMessages);
I have two action classes associated with the screen. One is called CertSigningQueueDisplayAction and the other is called CertSigningQueueUpdateAction. The first class is used to prepare the data for display and the second class is used to process the screen and any user updates.
As a result of this when the user presses the "save" button I use action chaining. First CertSigningQueueUpdateAction is called to process the screen and then CertSigningQueueDisplayAction is called to prepare the screen data for re-display.
The problem is when I call Action.saveMessages(request,actionMessages); in the CertSigningQueueUpdateAction class and then control goes to the CertSigningQueueDisplayAction class the ActionMessages attribute has been stripped from the http request object. How come? Why would Action chaining cause the ActionMessages attribute to be removed? It's still the same http request object, right?
It looks like Struts is initializing the actionMessages each time an action is called. If you look at the struts documentation, it says that action chaining is allowed but not recommended. This may be one of the reasons why it's not recommended.
It shouldn't be hard to work around this, though. Just have the first action put the message key in the request and have the second action check for it's existence, and if so add it to actionMessages.
Yeah, no problem with working around the issue. I just could not figure out why I would have to. The documentation inidicates that if you are doing more than one action chaining you are probably putting too much business logic in your action classes. OK, I buy that.
The thinkg is our application is set up to use one Action class to prepare the screen data and a seperate Action class to to process the screen data. I've used this approach before and it works very well. In fact, I have incorporated this as one of my Struts "best practices". Am I the only one doing things this way?
Joined: Feb 15, 2005
I agree that having a setup action and a process action is not a bad way to go. I also don't see a good reason why the actionMessages has to be refreshed for every action. You may want to check later versions of Struts to see if they still do it that way. If so, you may want to submit a request to have it changed for future releases.
This is not the only good way to do things, though. I almost never do action chaining. For my applications almost all of the logic for both page setup and processing is delegated to other classes. When an action has to process data and setup another page, it just calls the appropriate methods in other classes. In my view, the ActionClass functions as a controller, and as such it's main function is to direct traffic to other classes to do the real work.
I'm not trying to convince you to change, however. Just to point out that there is room for more than one view of how to architect struts applications.
Joined: Feb 15, 2005
When I last posted to this thread, I was unable to find what I had remembered reading about chaing actions. I've found it since then.
As a rule, chaining Actions is not recommended. If your business classes are properly factored, you should be able to call whatever methods you need from any Action, without splicing them together into a cybernetic Rube Goldberg device.
If you must chain Actions, be aware of the following: calling the second Action from the first Action has the same effect as calling the second Action from scratch. If both of your Actions change the properties of a formbean, the changes made by the first Action will be lost because Struts calls the reset() method on the formbean when the second Action is called.
[ December 16, 2005: Message edited by: Merrill Higginson ]
Joined: Sep 08, 2004
OK, I guess I'm trying to do something in a somewhat non-recommended way.
Since we're on the subject I have to say that it seems to me if you use a single Action class for a data input screen you will end up with an Action.execute(...) of the following form:
In other words you have two almost completely different sets of functionality based on whether you are preparing or processing the data. The first thing you do when entering the execute() method is to figure out which set of functionality should be invoked. Generally when I see something like this I refactor it so each set of functionality has it's own class, or at least it's own method.
Isn't that standard practice?
Joined: Feb 15, 2005
No one is disputing that the case you've presented could be handled better by two classes. Let me preset a sample case that I think clarifies the difference between the two approaches.
The code below presents a case of a simple login screen that then forwards to a customer home screen.
Here's pseudo-code for the non-action-chaining approach:
Here's the chaining approach:
As I see it, there's not really that much difference in these two approaches. It's just a matter of what code you feel is appropriate to put in the action and what code should be delegated to other classes.
One thing I like about the non-chaining approach is that it's easier to do things in process Login to change the way the Login screen is displayed when there's an error condition as opposed to the way it's displayed initially. I also like the idea of having a single method that gives me a broad overview of evertything that's happening in that interaction with the server. The disadvatage, of course, is that you have more classes to deal with.
[ December 16, 2005: Message edited by: Merrill Higginson ] [ December 16, 2005: Message edited by: Merrill Higginson ]