This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I'm using org.apaches.struts.actions.LookupDispatchAction to process different form submissions from the same page. There are several buttons on the page that will submit the form. I want a specific method in the Action class to process a specific form button. That's what LookupDispatchAction is for, right?
My problem is that it seems that buttons must be labelled distinctly, but I want to label them all with the same value.
Here's a represenative button declaration on the page:
This is how I've declared the labels in ApplicationResources:
In my Action class (which extends LookupDispatchAction), the keyMethodMap looks like this:
My struts-config is set up properly and the page renders correctly. But when I click one of the submit buttons, the most observed behavior is this: The method that gets called is the one associated with whatever message key appears last in ApplicationResources. In the scenario above, sumSales() is called regardless of which button I click. If I recode ApplicationResources such that the order is reversed (button,3, button.2, button.1), then sumInventory() is called - whatever button I click. If I rename the labels in ApplicationResources, e.g.
everything works fine.
I thought the whole point of LookupDispatchAction was to be able to use buttons with the same label but call different methods? I'm using Struts 1.1. Can this be a bug?
The point of LookupDispatchAction is to allow you to use internationalization with your pages, so that regarless of which language your page is displaying, the dispatch Action will still work. Apparently it doesn't work if the actual text being displayed is identical.
All I can do is suggest a work-around: Use DispatchAction instead of LookupDispatchAction. Then change all your buttons to <html:button> and create an <html:hidden property="action" /> field. In the on click event of each button, set the value of the hidden field to the method you want executed and submit the form.
Thanks Merril, that makes sense actually. DispatchAction is my next stop.
A somewhat related problem: For all my other actions I've coded an abstract class BaseAction that extends org.apache.struts.action.Action and my "user actions" extend BaseAction. In BaseAction I've got some methods that I consistently use from all actions. The execute() method is coded like this: executeAction() is an abstract method that I implement in my sub-classes.
Is there a way I can use Struts' other action classes (like DispatchAction) and still use the code I've coded in BaseAction without merely creating a BaseDispatchAction and repeating myself?
I don't see the reason why you can't extend DispatchAction in place of Action, in the BaseAction class, coz it doesn't matter if you extend Action, DispatchAction or LookUpDispatchAction; the execute() method is always called first. Only after calling the execute() method, the remaining methods get called. Hope this answers your query.
"What's in a name? That which we call a rose by any other name would smell just as sweet."<br />(William Shakespeare, Romeo and Juliet, Act II, Scene II)
Joined: Mar 08, 2006
Here's what I really want to do:but of course Java does not support multiple inheritance.
Joined: Feb 15, 2005
I think you're going to be better off just creating a separate base action for DispatchAction. If you tried to do everything in one base action, it could get messy. For a DispatchAction, it's the execute() method in the superclass that routes the request to the named method. If you tried to cover all situations in one base class, you'd have to call super.execute() in all cases, and then catch the error that it throws when there is no action parameter and no defined methods to execute. To me this is messy, and I think it's better just to use a separate base class when DispatchAction is required.
This is part of the reason that I have never been real excited about DispatchAction. I am sure there is a way to interject common functionality, but it is not obvious to me. Have you looked at the source code for DispatchAction? It is actually a very small class with one a hundred or so lines of code, and half of that is exception handling. You could easily do "reuse from cut and paste" if your really wanted the functionality of DispatchAction.