<!-- --><style type="text/css">@import url(https://www.blogger.com/static/v1/v-css/navbar/3334278262-classic.css); div.b-mobile {display:none;} </style> </head><body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d7256432\x26blogName\x3dThe+Frustrated+Programmer\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLACK\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttp://frustratedprogrammer.blogspot.com/search\x26blogLocale\x3den_US\x26v\x3d2\x26homepageUrl\x3dhttp://frustratedprogrammer.blogspot.com/\x26vt\x3d5012862196962223429', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>
| Saturday, July 17, 2004

When Struts introduced the DispatchAction, people initially thought it was a great idea, until it started to break down in the real world. One of those points of break down is canceling a form (and bypassing validation). See, Struts normally only looks for the parameter org.apache.struts.actoin.CANCEL to indicate cancellation of a form. But if a form has multiple buttons and uses DispatchAction to manage them. Its not easy to pass a method name AND this special Struts parameter. It can be done with JavaScript, but that needs to be cut and pasted to each file, so its not really an option.


In the past, I used to subclass my ActionForm class and add override the validate() method and skip validation if the cancel button was pressed:


// The struts dispatch action and the validator framework don't work well together. To cancel validation of
// a form, struts noramlly looks for the parameter "org.apache.struts.action.CANCEL", but with a dispatch
// action and a form with multiple buttons, we can't really do this. So I'm just going to look for
// the method of "cancel".
private static final String METHOD_CANCEL = "cancel";

public ActionErrors validate(ActionMapping mapping, javax.servlet.http.HttpServletRequest request)
{
if( request.getParameter( mapping.getParameter() ).equals( METHOD_CANCEL ) ) {
return new ActionErrors();
}
return super.validate( mapping, request );
}


This requires my method to be named cancel, but it seems to work fine.

With Struts 1.2.1 came with this release note:


Cancel handlers - DispatchAction,
LookupDispatchAction, and MappingDispatchAction - Now provide default
cancel handler that can be overridden. It also also possible to specify
the default handler name.



So looking into the JavaDoc they explain it a little more with:


NOTE - If the value of the request parameter is empty,
a method named unspecified is called. The default action is
to throw an exception. If the request was cancelled (a html:cancel
button was pressed), the custom handler cancelled will be used instead.
You can also override the getMethodName method to override the action's
default handler selection.
 

What does this mean? Well, if Struts sees the parameter 'org.apache.struts.action.CANCEL' in DispatchAction or one of its children, it will ignore the value of your parameter and call a method named cancelled(). This is a good thing, since you can use the tag html:cancel with a DispatchAction now.