You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Rick Reumann <r...@reumann.net> on 2004/09/09 18:34:05 UTC
Trying to come up with a Mapping-Dispatch combo Action
Not sure which list this question/topic really belongs on so posting to
both. (I'm bringing it up on the dev list because I'm thinking maybe the
base MappingDispatchAction could/should be modified).
Some design background. I like to keep related tasks belonging in one
Dispatch Action class (flavor to be discussed). This is a typical
approach, yet one of the problems is desided on the type of
DispatchAction ... keep it DispatchAction or use one of the subclasses
LookupDispatch or MappingDispatch.
First off I really don't like the LookupDispatchAction. I've used it
extensively in a large application and it becomes a real pain. It
becomes really ugly to use when you start having some generic button
names that you reuse for different things. For example a changing
requirment was that we ended up having to use a button called "Ok" a lot
(I know stupid). So sometimes "Ok" would submit to the same
LookupDispatchAction but would need to access different methods. You
end up then having to create 'fake' button names in your resources file
just so the LookupDispatchAction can work correctly. Maintenance of the
LookupDispatch can be a pain also. Anyway...
Until the MappingDispatchAction, I've been relatively content with using
a standard DispathAction. What I like about the MappingDispatchAction is
that it works really nicely for links - you don't have to append a
dispatch parameter name to the URL. It's also nice for typical forms
since you don't have to provide a hidden dispatch parameter on the page.
The only problem I'm running into it is when you have a form with more
than one button and each button should call a different dispatch method.
I haven't really figured out a good way to work this out with the
MappingDispatchAction. I think trying to change the form's action
attribute using JavaScript will be ugly (assuming it can even be done,
I've never tried it). The only solution I can think of at the moment
would be to override the getMethodName method of MappingDispatch and
provide an extra mapping in your config where the parameter would change
to something like parameter="dispatchMethod"
The overridden getMethodName might look like
protected String getMethodName(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response,
String parameter)
throws Exception {
if( "dispatchMethod".equals( parameter ) {
parameter = request.getParameter(parameter);
}
return parameter
}
This would allow you to use the MappingDispatchAction like a
DispatchActoin when needed. The only caveat is you would have to make
sure the if statement in the above is what you wanted. (Probably better
to pull the parameter name "dispatchMethod" from a properties file or
constants class).
Maybe there is a much better way to accomplish what I'm concerned with?
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Last try. Sorry about the noise:Rick Generic Action Solution
<link>----|
|
<image>---|--- to updateFooBar.do of some GenericAction class.
|
<submit>--|
Michael Generic Taglib Solution
<link>----|
| A: Solution Facade Interface:
<image>---| <facase: link, image, submit, file, etc.>
|---B: Solution Implementation:
| Unconnected to anything [Unknown Code]
| C: Generic Request Handler: updateFooBar.x
<submit>--| gives the action updateFooBar
| for all of these, in and out of Struts,
<file>----| e.g. with DispatchAction.
>
>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Hoping this comes out better:
Rick Generic Action Solution
<link>------|
|
<image>---|--- to updateFooBar.do of some GenericAction class.
|
<submit>--|
Michael Generic Taglib Solution
<link>----|
| A: Solution Facade Interface:
<image>---| <facase: link, image, submit, file, etc.>
|---B: Solution Implementation:
| Unconnected to anything [Unknown Code]
| C: Generic Request Handler: updateFooBar.x
<submit>--| gives the action updateFooBar
| for all of these, in and out of Struts,
<file>---- | e.g. with DispatchAction.
>
>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Rick Reumann wrote:
> Some comments below...
>
> Michael McGrady wrote the following on 9/13/2004 5:40 PM:
>
>
> Yes, that is a slight benefit (which is the same benefit of using the
> regular DispatchAction), however, the slight cost of having to rely on
> the struts-config for deciding what dispatch method is going to be
> called is worth it for the sake of consistency, since I don't have to
> worry about whether it's a link, button, image, or form submit. If I
> didn't want to use the struts-config simply using the standard
> DispatchAction works fine as well. Consistent.
I think what you are saying is that you like to use one action for
various view tags. So, you are looking for a struts action that gives
you one action for links, buttons, imges, and submits. (You don't
include, for good reason, the browse button for file uploads.)
Rick Generic Action Solution
<link>----------|
|
<image>------- | ------ to updateFooBar.do of some GenericAction class.
|
<submit>------ |
Michael Generic Taglib Solution
<link>----------|
|
<image>------- |
| A: Solution Facade Interface:
<facase: link, image, submit, file, etc.>
| ------- B: Solution Implementation:
Unconnected to anything [Unknown Code]
| C: Generic Request Handler:
updateFooBar.x gives the action updateFooBar for all of these,
| in and out of Struts,
e.g. with DispatchAction.
<submit>-------|
|
<file>-----------|
So, I guess we are doing things a bit differently but in a very
connected way both coding-wise and "philosophy-wise". Right? I still
am EXTREMELY interested in your questions and your progress. If I am
not mistaken, you can use DispatchAction to do what you want with my
solution. I am beginning to see the use of your concerns with respect
to Struts. In fact, something not unlike DispatchAction can be used to
do what you with my solution outside of struts entirely. Isn't that
correct? Perhaps the two together could form a real dynamo? I have
more in the wings working with the taglibs sandbox image stuff, which is
excellent, by the way.
Michael McGfady
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Rick Reumann wrote:
> Some comments below...
>
> Michael McGrady wrote the following on 9/13/2004 5:40 PM:
>
> Thanks for your comments below. It has helped clarify things. Your
> approach is pretty nice but in the above how would you be able to use
> this same Action for regular links? It seems like you have tied this
> Action to requiring use of hte ImageTagUtil which doesn't make too
> much sense for when you'd want to get to this action class from a
> standard link?
Hi, Rick,
We are getting someplace here, I think. I don't use this Action at
all. I just made this little class up to show what I was talking
about. Tying the solution to these things just ruins performance and
flexibility. Decoupling, I have always thought, is like Aaron
Nitzovitch's theory of "over protection" in chess. If you have too much
protection on a square, then none of the pieces involved is critical and
so all are free to operate as offensive weapons. What I am trying to
say is that I use a Facade, which means that the Facade is the standard
interface for all the differing page operations we were discussing. I
don't try to use an Action or any other particular solution outside the
Facade to do this. The <crackwillow:image/>, <crackwillow:file/>,
<crackwillow:link/> , ... , etc. tag is the Facade. I am trying to
advocate that the correct solution for a generic approach is a Facade
represented by a taglib covering all the options that are relevant.
This Facade is not even wedded to struts. I do use struts, but that is
not necessary. That is but a "component" of the mix behind the Facade.
That's what I do. Now, can you expand on what you do with
MappedLookupAction?
I suspect we are working on differing attempts at "generic apporaches".
Mine is related to what is written on the JSP page and yours, I think,
is related to finding a generic approach with struts actions. Exactly
what you are doing is not clear to me.
By the way, did you see the post by Craig on MappedLookupAction today?
Michael McGrady
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Rick Reumann <st...@reumann.net>.
Some comments below...
Michael McGrady wrote the following on 9/13/2004 5:40 PM:
> The following class works fine:
>
> public abstract class CrackWillowLookupDispatchAction
> extends DispatchAction {
>
> public ActionForward execute(
> ActionMapping mapping,
> ActionForm form,
> HttpServletRequest request,
> HttpServletResponse response)
> throws Exception {
> String methodName = ImageTagUtil.getName(request);
> return dispatchMethod(mapping, form, request, response, methodName);
> }
> }
Thanks for your comments below. It has helped clarify things. Your
approach is pretty nice but in the above how would you be able to use
this same Action for regular links? It seems like you have tied this
Action to requiring use of hte ImageTagUtil which doesn't make too much
sense for when you'd want to get to this action class from a standard
link? (This was also my problem with the LookupDispatchAction that I
didn't like... MappingDispatchAction solves all of this).
> The other issues about this action have nothing to do with what I have
> been talking about, I think.
>
> <html:form name='lookupForm' method='get' action='lookup.do'
> type='com.crackwillow.struts.form.LookupForm'>
> <input type='submit' name='add.x' value='add'>
> <input type='submit' name='delete.x' value='delete'>
> </html:form>
>
> This requires nothing in struts-config.xml.
Yes, that is a slight benefit (which is the same benefit of using the
regular DispatchAction), however, the slight cost of having to rely on
the struts-config for deciding what dispatch method is going to be
called is worth it for the sake of consistency, since I don't have to
worry about whether it's a link, button, image, or form submit. If I
didn't want to use the struts-config simply using the standard
DispatchAction works fine as well. Consistent.
<snip>
>
> What my image is has nothing to do with what the name value is. The
> name value is the command and is completely decoupled from the
> image.
Yes, I see that now. That's good. Thanks for that clarification.
> The following simple code, in my solution, can replace a hugely
> complex series of relations and code in LookupActionMapping which
> drive you crazy and make any connection with ActionMapping's
> parameter attribute unnecessary as well.
Agreed. And definitely if I was going to go with a dispatch approach
that relied on img/button names yours is a much more elequent solution.
(I still like an onClick to a MappingDipsatchAction though:)
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
I am enjoying the discussion as well.
I can see that your schedule and my attempting to say too much are
confusing things. Let me also clarify a couple things so we are clear
what we each are saying. Then I will address the bigger issues.
The following class works fine:
public abstract class CrackWillowLookupDispatchAction
extends DispatchAction {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
String methodName = ImageTagUtil.getName(request);
return dispatchMethod(mapping, form, request, response, methodName);
}
}
The other issues about this action have nothing to do with what I have
been talking about, I think.
<html:form name='lookupForm' method='get' action='lookup.do'
type='com.crackwillow.struts.form.LookupForm'>
<input type='submit' name='add.x' value='add'>
<input type='submit' name='delete.x' value='delete'>
</html:form>
This requires nothing in struts-config.xml.
I. Clarifications
A. Code Inside ActionForm Topic
The code I use for determining which <input type='image'> button has
been pressed is this utility class and this utility class alone.
public class ImageTagUtil {
public static String getName(HttpServletRequest request) {
String command = null;
String buttonValue = null;
Enumeration enum = request.getParameterNames();
while(enum.hasMoreElements()) {
buttonValue = (String)enum.nextElement();
if(buttonValue.endsWith(".x")) {
command = buttonValue.substring(0,buttonValue.indexOf('.'));
}
}
return command;
}
}
The code in the form (inner class buttons) is an improvement on
other solutions where there are button classes used. I don't like
those solutions, including mine, which I think is better than the
usual. The usual solution ends up really heavy with loads of
buttons populating the situation,whereas this solution (which I
don't like, remember) uses one inner button and one only. But, I
don't use this at all. I removed it from the wiki as too complicating.
B. Different Commands for Different Images
What my image is has nothing to do with what the name value is. The
name value is the command and is completely decoupled from the
image. Neither has anything to do with the other. You can change
the image to anything you want and you can change the command to
anything you want. This is clearly true with the html too. <input
type='image' src='whatever.gif' name='whatever'> clearly decouples
what the gif is and what the name attribute value is. I extend this
by providing a tag which will produce an image with says whatever
it's name is: 'WHATEVER.gif' will be a gif with "WHATEVER",
'Whatever.jpg' will be a jpeg with "Whatever". So, we can have
"OK.gif" with name='viewFoo' and "OK.gif" with name='updateFoo'.
That is not a problem. If they later decide that they want
"Yahoo.gif" or "GO.jpg" instead of "OK.gif", all you have to do is
change it and nothing else changes at all.
II. Issues
A. LookupActionMapping
My solution does not say a thing about using or not using the idea
of executing a method by something like LookupActionMapping. Rather
it is wholly about how to mine the values from the HTML.
The following simple code, in my solution, can replace a hugely
complex series of relations and code in LookupActionMapping which
drive you crazy and make any connection with ActionMapping's
parameter attribute unnecessary as well.
execute(execute(ActionMapping mapping, ActionForm
form,HttpServletRequest request, HttpServletResponse response) {
return dispatchMethod(mapping, form, request, response,
ImageTagUtil.getName(request));
}
So, the LookupActionMapping requires you IN ORDER TO ACHIEVE THE
SAME THING to give the parameter attribute a value in the action
mapping of struts-config.xml whereas my solution is completely
decoupled from that. The LookupDispatchAction requires you to
implement keyMethodMap relating methods to both the JSP and the
action mapping of struts-config.xml. The fact that
LookupDispatchAction uses reflection is important, of course, but is
completely irrelevant to the principal ideas that
LookupDispatchAction is based on. Other ways of mining the value of
the method to be used can equally subclass DispatchAction.
Michael McGrady
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Rick Reumann <st...@reumann.net>.
(not commenting below, just up top on this)
In reference to your first comment:
> I think that what appears to be a model emphasis for the
> solution in your [rick's] approach is bound to fail. Further, making
> the
> solution view based frees the model to be built for performance, which
> is why I use the solution I sent to you with respect to images, i.e.
> the image tag for submits.
Maybe you are misunderstanding what I'm doing. My approach has nothing
to do with the model at all. All I have is a very simple
MappingDispatchAction with typical dispatch methods.
All my links, forms, or image 'onClicks' simply equate to a standard
mapping (ie /updateFooBar.do... /viewFooBars.do, etc). So a developer
can ALWAYS easily tell what is being called (of course to see the actual
method being called he/she will need to look in the struts-config but
it's consistent across all types of front end calls.
I saw two things in the initial e-mail that had me concerned. One was
where the tag had this code:
if(buttonValue.endsWith(".x")) {
command = buttonValue.substring(0,buttonValue.indexOf('.'));
}
}
return command;
The second was all the code you added inside of your ActionForm
subclass... even to the extent that it needs to contain an inner class.
I just find this to be way overcomplicated for something that I think
should be pretty simple.
In reference to my first concern... How would you have two different
commands executed for a button with the same name? In my case here at
work, we had to develop this one app where we needed to use an "Ok"
button. If I was on an edit page I needed to still have an "Ok" button
and when on an insert page I still had to use the same "Ok" button.
Looks like in your above, this would end up calling on the one type of
method. (It also looked like you would run into the same problem with
the CrackWillowButton class).
I guess what I am missing is what your approach gains me verses using
just a 'tiny' amount of javascript. (I'm not one to believe that a web
application in today's world should be required to work without ANY
javascript).
I'll sum up my approach with examples and would love to hear the
problems with it. Keep in mind the advantage (I think) to this is that
you simple code your standard MappingDispatchAction and that you can
'easily' see what is being called. In ALL the example below you easily
see the action being called (no need to figure what underlying
implementation is taking care of figuring out what dispatch method to
call, you easily can just look at your mapping and find out.)
Enjoying this discussion. Hopefully below it makes it more clear what
I'm doing:
UserAction of type MappingDispatchAction with some typical dispatch methods
ie updateUser, insertUser, deleteUser, getUser, getUsers
(mappings in struts-config could look identical to the above which of
course map to "UserAction")
Different ways you could get access to the methods:
1) From a link. (I like JSTL even though a bit more verbose than html:link):
<c:url var="url" value="/getUsers.do"/><a href="${url}">[ Get Users ]</a>
2) From a typical form with one submit button
<html:form action="/updateUser">
<html:submit><fmt:message key="button.update"/></html:submit>
3) For images or buttons
<c:url var="url" scope="page" value="/getUser.do">
<c:param name="id" value="${user.id}"/>
</c:url>
//on button or img onClick, or I usually make this a js function:
window.location='${url}'
4) When you need different submit buttons for one form
//create a javascript function. I keep this in my header.jsp
//Thanks Bill (I think it was Bill S. who posted this:)
function swapAction( formName, action) {
formAction = document.getElementById( formName ).action;
newAction = '<html:rewrite page="/'+action+'.do"/>';
document.getElementById( formName ).action = newAction;
}
//then on different submit buttons
<html:submit onclick="swapAction( 'userForm', 'updateUser')">
<fmt:message key="button.update"/>
</html:submit>
Michael McGrady wrote the following on 9/13/2004 11:09 AM:
> SEE WITHIN:
>
> Michael McGrady
>
> Rick Reumann wrote:
>
> I hope you have a bit of time to discuss this in detail, Rick, because
> the amount of activity in this area is huge. I think this is one of
> those areas, along with looking for persistence not identical to the
> normal scopes, where there is continued dissatisfaction.
>
>>
>> First I'd like to point out that I like to keep an application as
>> consistent as possible. That means that I like my links, my form
>> submits, my buttons to all act similarly - this makes it very easy for
>> a new developer to the project to figure out what is going on.
>
>
> I do too. My generic solution is based on what appears on the "coded"
> page. I wanted to decouple that from everything else. I, therefore,
> use a variation of the FACADE PATTERN with these, emphasizing a generic
> solution from the VIEW perspective rather than from the MODEL
> perspective. I think that what appears to be a model emphasis for the
> solution in your approach is bound to fail. Further, making the
> solution view based frees the model to be built for performance, which
> is why I use the solution I sent to you with respect to images, i.e. the
> image tag for submits.
>
> There simply is not a model based generic solution, in my opinion, which
> sometimes if right and sometimes is wrong. (I also include <input
> type='file'>, by the way, in addition to your list.) I think you have
> to use something like the Facade Pattern because the actual logic
> underlying these view related behaviors is so different. If you try to
> disseminate a generic solution in the model, you are bound to run into
> the types of problems you have discussed. So, essentially, I have
> developed a taglib that looks like this:
>
> GENERIC PAGE BASED SOLUTION
>
> <crackwillow:image
> button='Crack_Willow_Chat.gif'
> mapBean='hkc'
> bgClrCode='banRtBgClr'
> txtClrCode='banRtTxtClr'
> font='Edwardian Script ITC'
> italic='false'
> bold='true'
> size='30'
> property='chatSend'/>
>
> The key here is the "image". If you wanted to browse with an input type
> of file, this would be "file". This produces a GIF button saying "Crack
> Willow Chat" in Edwardian Script ITC embolded with a size of 30 and a
> coded identification of the command as "chatSend" and whatever colors
> happen to be represented in this space by the values of bgClrCode
> (background color) and txtClrCode (text color). If you want a jpeg, put
> in ".jpg", etc. If you don't want a button, just drop ".gif" entirely.
> The behavior of the button is changed by changing "image", e.g.
> "submit", "link", "file". The view value of the button itself is
> changed by changing the value of "button". This is fully localized. If
> you don't want a And the property you want to send is changed with a
> change in "property". The colors are dynamic here with bgClrCode and
> txtClrCode. If you wanted to hard code them, you would with bgClr and
> txtClr. The value of property can be dynamic or not. This depends on
> the model coders. The map bean, which is instrumented, allows me to
> connect the dynamic colors with other colors on a page, which are held
> in the same bean. Any other model solution for that problem can easily
> be plugged into this solution.
>
> Here is the rub or the main point. The solution I sent to you is
> decoupled from this page code, emphasizing the use of the Facade
> Pattern. Accordingly, I send parts of my solution out each time a
> question comes up in the area, but never the whole solution, which is
> too involved for simple posts. (Images, for example, are created
> dynamically and cached.)
>
> This solution presently lets me just put in my buttons and have no
> concern at all for what happens in the background. Some parts of the
> solution, e.g. for <input type='file'>, will generate JavaScript and
> others won't. I use a mock image over the "live" image of the file
> browse button in order to get dynamic, image buttons for the browse
> button that are consistent with the security protocols for <input
> type='file'>. Further, the background code for this is decoupled from
> the model because the model simply has to deal with results rather than
> with mining the results. I place the class* */ImageTagUtil /cited in my
> last to you between the form and the Action. Thus, Actions don't care
> if it is an image, a submit, or whatever.
>
> You get the idea. What do you think?
>
> Michael McGrady
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
SEE WITHIN:
Michael McGrady
Rick Reumann wrote:
I hope you have a bit of time to discuss this in detail, Rick, because
the amount of activity in this area is huge. I think this is one of
those areas, along with looking for persistence not identical to the
normal scopes, where there is continued dissatisfaction.
>
> First I'd like to point out that I like to keep an application as
> consistent as possible. That means that I like my links, my form
> submits, my buttons to all act similarly - this makes it very easy for
> a new developer to the project to figure out what is going on.
I do too. My generic solution is based on what appears on the "coded"
page. I wanted to decouple that from everything else. I, therefore,
use a variation of the FACADE PATTERN with these, emphasizing a generic
solution from the VIEW perspective rather than from the MODEL
perspective. I think that what appears to be a model emphasis for the
solution in your approach is bound to fail. Further, making the
solution view based frees the model to be built for performance, which
is why I use the solution I sent to you with respect to images, i.e. the
image tag for submits.
There simply is not a model based generic solution, in my opinion, which
sometimes if right and sometimes is wrong. (I also include <input
type='file'>, by the way, in addition to your list.) I think you have
to use something like the Facade Pattern because the actual logic
underlying these view related behaviors is so different. If you try to
disseminate a generic solution in the model, you are bound to run into
the types of problems you have discussed. So, essentially, I have
developed a taglib that looks like this:
GENERIC PAGE BASED SOLUTION
<crackwillow:image
button='Crack_Willow_Chat.gif'
mapBean='hkc'
bgClrCode='banRtBgClr'
txtClrCode='banRtTxtClr'
font='Edwardian Script ITC'
italic='false'
bold='true'
size='30'
property='chatSend'/>
The key here is the "image". If you wanted to browse with an input type
of file, this would be "file". This produces a GIF button saying "Crack
Willow Chat" in Edwardian Script ITC embolded with a size of 30 and a
coded identification of the command as "chatSend" and whatever colors
happen to be represented in this space by the values of bgClrCode
(background color) and txtClrCode (text color). If you want a jpeg, put
in ".jpg", etc. If you don't want a button, just drop ".gif" entirely.
The behavior of the button is changed by changing "image", e.g.
"submit", "link", "file". The view value of the button itself is
changed by changing the value of "button". This is fully localized. If
you don't want a And the property you want to send is changed with a
change in "property". The colors are dynamic here with bgClrCode and
txtClrCode. If you wanted to hard code them, you would with bgClr and
txtClr. The value of property can be dynamic or not. This depends on
the model coders. The map bean, which is instrumented, allows me to
connect the dynamic colors with other colors on a page, which are held
in the same bean. Any other model solution for that problem can easily
be plugged into this solution.
Here is the rub or the main point. The solution I sent to you is
decoupled from this page code, emphasizing the use of the Facade
Pattern. Accordingly, I send parts of my solution out each time a
question comes up in the area, but never the whole solution, which is
too involved for simple posts. (Images, for example, are created
dynamically and cached.)
This solution presently lets me just put in my buttons and have no
concern at all for what happens in the background. Some parts of the
solution, e.g. for <input type='file'>, will generate JavaScript and
others won't. I use a mock image over the "live" image of the file
browse button in order to get dynamic, image buttons for the browse
button that are consistent with the security protocols for <input
type='file'>. Further, the background code for this is decoupled from
the model because the model simply has to deal with results rather than
with mining the results. I place the class* */ImageTagUtil /cited in my
last to you between the form and the Action. Thus, Actions don't care
if it is an image, a submit, or whatever.
You get the idea. What do you think?
Michael McGrady
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Rick Reumann <st...@reumann.net>.
Hi Michael. I'm replying to his quickly before I run into work so I
might not have looked these approaches over enough but here are my first
impressions.
First I'd like to point out that I like to keep an application as
consistent as possible. That means that I like my links, my form
submits, my buttons to all act similarly - this makes it very easy for a
new developer to the project to figure out what is going on.
Concerning the first approach, it appears the type of command called has
to match the button name. I don't like this approach at all. Sometimes
you later need to change the button names or even a worse scenario, you
sometimes need to have the same button name used on different forms go
to the same Action class but call a different dispatch method (for
example with the "ok" or "proceed" button).
The second approach runs into some of the same of problems as the
LookupDispathAction.. maintenance problems. In that approach you have to
maintain what action method gets called by editing an ActionForm class.
This becomes sort of unintuitive. It works but to me it just does
provide for a consistent approach.
What I like about the simple use of MappingDispatchAction, and using
some extremely simple javascript for button situations, is that the
approach is easy to follow. For a developer to figure what action
dispatch method is going to be called he/she simply always can tell by
the MappingDispatch mapping. This works for links, form submits and for
button submits. (I'm thinking the later approach you mentioned would
work with links and form submits but would then require you always pass
in a request parameter that matches a button name similar to what you
need to do when using a LookupDispatchAction).
Another feature I like of just always using a MappingDispatchAction is
that maintenance seems easier. The only things you maintain are an
action mapping in your struts config (which you always have to have
anyway) and a dispatch method name (which you always need also). There
is no need to worry about maintaining any button names and what they
correspond to. You end up not caring about how they get to your Action
dispatch method and you let the pure view(JSP) worry about calling the
proper action mapping. Just my preference I guess for consistency's sake.
Michael McGrady wrote the following on 9/13/2004 2:48 AM:
> *The following is from
> http://wiki.apache.org/struts/StrutsCatalogMultipleImageTagsSimplified
> . If you don't like this solution, I would be interested in your
> thinking, Rick. If you are interested, I have a comprehensive solution
> to everything to do with buttons and images. I am going to add to it,
> but it is pretty well developed.
> *
>
> *This is an efficient way to end forever that pesky and recurrent
> problem of how to use multiple image buttons in your forms. (N.B.:
> This solution also works for non-image (submit) buttons by using
> values like <input type="submit" name="add.x" value="add"> in the
> submit button. Or, just use <input type="submit" name="button"
> value="add"> for a different solution for <input type="submit">
> versus <input type="image">)*
>
> *Assume that you have code not unlike:*
>
> <input type='image' name='update' src='change.gif'>
> <input type='image' name='delete' src='nuke.gif'>
>
> *or, in Struts' image tag:*
>
> <html:image property='submit' src='change.gif'/>
> <html:image property='delete' src='nuke.gif'/>
>
> *Now, how do we know which image has been clicked? The answer has
> been complicated and costly in the past. Here is a simple way to
> achieve everything at a low cost and with great flexibility and
> freedom.*
>
> String button = null;
> Enumeration enum = request.getParameterNames();
> String parameterName = null;
> while(enum.hasMoreElements()) {
> parameterName = (String)enum.nextElement();
> if(parameterName.endsWith(".x")) {
> button = parameterName.substring(0,parameterName.indexOf('.'));
> }
> }
>
> *There you go. /If you clicked the image with name='submit', then
> the variable button will have the value "submit"./ I suggest that
> you toss out the LookupDispatchActions, the ButtonCommands, etc.
> This is a done deal. You can clearly seek other ways to ensure a bit
> more safety. For example, the code works equally as well with
> "submit.button" as it does with "submit". Elegant, no, eh? I use a
> class that encapsulates this functionality as follows:** *
>
> *public class ImageTagUtil {
> public static String getName(HttpServletRequest request) {
> String command = null;
> String buttonValue = null;
> Enumeration enum = request.getParameterNames();
>
> while(enum.hasMoreElements()) {
> buttonValue = (String)enum.nextElement();
> if(buttonValue.endsWith(".x")) {
> command = buttonValue.substring(0,buttonValue.indexOf('.'));
> }
> }
> return command;
> }
> }
> *
>
> *Surprisingly, some people still prefer the way I used to do this. I
> think they just like the plain fanciness of it all. For those
> people, here is code that is less extensible, more coupled, heavier,
> etc. This code is comparatively not as good, in my opinion. There is
> a further use of button objects which requires that you create a
> separate button object for each image button you use on an html
> page. That solution is very heavy and significantly affects the
> footprint of a struts page. /If/ you are going to use buttons,
> /which, again, is not recommended/, I would suggest the following
> more lightweight version, which creates and then nulls one button
> object per request. The use of an inner class allows the necessary
> communications between the action form and the button class. *
>
> *public class AdminButtonForm
> extends ActionForm {
> protected CrackWillowButton button;
> protected String command;
>
> public CrackWillowButton getButton() {
> if(button == null) {
> this.button = new CrackWillowButton();
> }
> return button;
> }
>
> public String getCommand() {
> String hold = command;
> command = null;
> return hold;
> }
>
> public void setCommand(String command) {
> this.command = command;
> }
>
> public void reset() {
> button = null;
> }
>
> public class CrackWillowButton {
> private Integer x, y;
> public static final String CREATE = "create";
> public static final String RETRIEVE = "retrieve";
> public static final String UPDATE = "update";
> public static final String DELETE = "delete";
> public static final String SUBMIT = "submit";
>
> public CrackWillowButton() {
> }
>
> public CrackWillowButton getCreate() {
> setCommand(this.CREATE);
> return button;
> }
>
> public CrackWillowButton getRetrieve() {
> setCommand(this.RETRIEVE);
> return button;
> }
>
> public CrackWillowButton getUpdate() {
> setCommand(this.UPDATE);
> return button;
> }
>
> public CrackWillowButton getDelete() {
> setCommand(this.DELETE);
> return button;
> }
>
> public CrackWillowButton getSubmit() {
> setCommand(this.SUBMIT);
> return button;
> }
>
> public void setX(Integer x) {
> if(y != null) {
> reset();
> } else {
> this.x = x;
> }
> }
>
> public void setY(Integer y) {
> if(x != null) {
> reset();
> } else {
> this.y = y;
> }
> }
> }
> }
> *
>
> *So, don't use buttons, but just mine the value of the [name].x
> request parameter. *
>
> *Michael McGrady Cap't of the Eh Team*
>
> Anyway, looking forward to you thinking on this.
>
> Michael
>
> Rick Reumann wrote:
>
>> Not sure which list this question/topic really belongs on so posting
>> to both. (I'm bringing it up on the dev list because I'm thinking
>> maybe the base MappingDispatchAction could/should be modified).
>>
>> Some design background. I like to keep related tasks belonging in one
>> Dispatch Action class (flavor to be discussed). This is a typical
>> approach, yet one of the problems is desided on the type of
>> DispatchAction ... keep it DispatchAction or use one of the subclasses
>> LookupDispatch or MappingDispatch.
>>
>> First off I really don't like the LookupDispatchAction. I've used it
>> extensively in a large application and it becomes a real pain. It
>> becomes really ugly to use when you start having some generic button
>> names that you reuse for different things. For example a changing
>> requirment was that we ended up having to use a button called "Ok" a
>> lot (I know stupid). So sometimes "Ok" would submit to the same
>> LookupDispatchAction but would need to access different methods. You
>> end up then having to create 'fake' button names in your resources
>> file just so the LookupDispatchAction can work correctly. Maintenance
>> of the LookupDispatch can be a pain also. Anyway...
>>
>> Until the MappingDispatchAction, I've been relatively content with
>> using a standard DispathAction. What I like about the
>> MappingDispatchAction is that it works really nicely for links - you
>> don't have to append a dispatch parameter name to the URL. It's also
>> nice for typical forms since you don't have to provide a hidden
>> dispatch parameter on the page.
>>
>> The only problem I'm running into it is when you have a form with more
>> than one button and each button should call a different dispatch
>> method. I haven't really figured out a good way to work this out with
>> the MappingDispatchAction. I think trying to change the form's action
>> attribute using JavaScript will be ugly (assuming it can even be done,
>> I've never tried it). The only solution I can think of at the moment
>> would be to override the getMethodName method of MappingDispatch and
>> provide an extra mapping in your config where the parameter would
>> change to something like parameter="dispatchMethod"
>>
>> The overridden getMethodName might look like
>>
>> protected String getMethodName(
>> ActionMapping mapping,
>> ActionForm form,
>> HttpServletRequest request,
>> HttpServletResponse response,
>> String parameter)
>> throws Exception {
>> if( "dispatchMethod".equals( parameter ) {
>> parameter = request.getParameter(parameter);
>> }
>> return parameter
>> }
>>
>> This would allow you to use the MappingDispatchAction like a
>> DispatchActoin when needed. The only caveat is you would have to make
>> sure the if statement in the above is what you wanted. (Probably
>> better to pull the parameter name "dispatchMethod" from a properties
>> file or constants class).
>>
>> Maybe there is a much better way to accomplish what I'm concerned with?
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: Trying to come up with a Mapping-Dispatch combo Action
Posted by Michael McGrady <mi...@michaelmcgrady.com>.
*The following is from
http://wiki.apache.org/struts/StrutsCatalogMultipleImageTagsSimplified
. If you don't like this solution, I would be interested in your
thinking, Rick. If you are interested, I have a comprehensive solution
to everything to do with buttons and images. I am going to add to it,
but it is pretty well developed.
*
*This is an efficient way to end forever that pesky and recurrent
problem of how to use multiple image buttons in your forms. (N.B.:
This solution also works for non-image (submit) buttons by using
values like <input type="submit" name="add.x" value="add"> in the
submit button. Or, just use <input type="submit" name="button"
value="add"> for a different solution for <input type="submit">
versus <input type="image">)*
*Assume that you have code not unlike:*
<input type='image' name='update' src='change.gif'>
<input type='image' name='delete' src='nuke.gif'>
*or, in Struts' image tag:*
<html:image property='submit' src='change.gif'/>
<html:image property='delete' src='nuke.gif'/>
*Now, how do we know which image has been clicked? The answer has
been complicated and costly in the past. Here is a simple way to
achieve everything at a low cost and with great flexibility and
freedom.*
String button = null;
Enumeration enum = request.getParameterNames();
String parameterName = null;
while(enum.hasMoreElements()) {
parameterName = (String)enum.nextElement();
if(parameterName.endsWith(".x")) {
button = parameterName.substring(0,parameterName.indexOf('.'));
}
}
*There you go. /If you clicked the image with name='submit', then
the variable button will have the value "submit"./ I suggest that
you toss out the LookupDispatchActions, the ButtonCommands, etc.
This is a done deal. You can clearly seek other ways to ensure a bit
more safety. For example, the code works equally as well with
"submit.button" as it does with "submit". Elegant, no, eh? I use a
class that encapsulates this functionality as follows:** *
*public class ImageTagUtil {
public static String getName(HttpServletRequest request) {
String command = null;
String buttonValue = null;
Enumeration enum = request.getParameterNames();
while(enum.hasMoreElements()) {
buttonValue = (String)enum.nextElement();
if(buttonValue.endsWith(".x")) {
command = buttonValue.substring(0,buttonValue.indexOf('.'));
}
}
return command;
}
}
*
*Surprisingly, some people still prefer the way I used to do this. I
think they just like the plain fanciness of it all. For those
people, here is code that is less extensible, more coupled, heavier,
etc. This code is comparatively not as good, in my opinion. There is
a further use of button objects which requires that you create a
separate button object for each image button you use on an html
page. That solution is very heavy and significantly affects the
footprint of a struts page. /If/ you are going to use buttons,
/which, again, is not recommended/, I would suggest the following
more lightweight version, which creates and then nulls one button
object per request. The use of an inner class allows the necessary
communications between the action form and the button class. *
*public class AdminButtonForm
extends ActionForm {
protected CrackWillowButton button;
protected String command;
public CrackWillowButton getButton() {
if(button == null) {
this.button = new CrackWillowButton();
}
return button;
}
public String getCommand() {
String hold = command;
command = null;
return hold;
}
public void setCommand(String command) {
this.command = command;
}
public void reset() {
button = null;
}
public class CrackWillowButton {
private Integer x, y;
public static final String CREATE = "create";
public static final String RETRIEVE = "retrieve";
public static final String UPDATE = "update";
public static final String DELETE = "delete";
public static final String SUBMIT = "submit";
public CrackWillowButton() {
}
public CrackWillowButton getCreate() {
setCommand(this.CREATE);
return button;
}
public CrackWillowButton getRetrieve() {
setCommand(this.RETRIEVE);
return button;
}
public CrackWillowButton getUpdate() {
setCommand(this.UPDATE);
return button;
}
public CrackWillowButton getDelete() {
setCommand(this.DELETE);
return button;
}
public CrackWillowButton getSubmit() {
setCommand(this.SUBMIT);
return button;
}
public void setX(Integer x) {
if(y != null) {
reset();
} else {
this.x = x;
}
}
public void setY(Integer y) {
if(x != null) {
reset();
} else {
this.y = y;
}
}
}
}
*
*So, don't use buttons, but just mine the value of the [name].x
request parameter. *
*Michael McGrady Cap't of the Eh Team*
Anyway, looking forward to you thinking on this.
Michael
Rick Reumann wrote:
> Not sure which list this question/topic really belongs on so posting
> to both. (I'm bringing it up on the dev list because I'm thinking
> maybe the base MappingDispatchAction could/should be modified).
>
> Some design background. I like to keep related tasks belonging in one
> Dispatch Action class (flavor to be discussed). This is a typical
> approach, yet one of the problems is desided on the type of
> DispatchAction ... keep it DispatchAction or use one of the subclasses
> LookupDispatch or MappingDispatch.
>
> First off I really don't like the LookupDispatchAction. I've used it
> extensively in a large application and it becomes a real pain. It
> becomes really ugly to use when you start having some generic button
> names that you reuse for different things. For example a changing
> requirment was that we ended up having to use a button called "Ok" a
> lot (I know stupid). So sometimes "Ok" would submit to the same
> LookupDispatchAction but would need to access different methods. You
> end up then having to create 'fake' button names in your resources
> file just so the LookupDispatchAction can work correctly. Maintenance
> of the LookupDispatch can be a pain also. Anyway...
>
> Until the MappingDispatchAction, I've been relatively content with
> using a standard DispathAction. What I like about the
> MappingDispatchAction is that it works really nicely for links - you
> don't have to append a dispatch parameter name to the URL. It's also
> nice for typical forms since you don't have to provide a hidden
> dispatch parameter on the page.
>
> The only problem I'm running into it is when you have a form with more
> than one button and each button should call a different dispatch
> method. I haven't really figured out a good way to work this out with
> the MappingDispatchAction. I think trying to change the form's action
> attribute using JavaScript will be ugly (assuming it can even be done,
> I've never tried it). The only solution I can think of at the moment
> would be to override the getMethodName method of MappingDispatch and
> provide an extra mapping in your config where the parameter would
> change to something like parameter="dispatchMethod"
>
> The overridden getMethodName might look like
>
> protected String getMethodName(
> ActionMapping mapping,
> ActionForm form,
> HttpServletRequest request,
> HttpServletResponse response,
> String parameter)
> throws Exception {
>
> if( "dispatchMethod".equals( parameter ) {
> parameter = request.getParameter(parameter);
> }
> return parameter
> }
>
> This would allow you to use the MappingDispatchAction like a
> DispatchActoin when needed. The only caveat is you would have to make
> sure the if statement in the above is what you wanted. (Probably
> better to pull the parameter name "dispatchMethod" from a properties
> file or constants class).
>
> Maybe there is a much better way to accomplish what I'm concerned with?
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org