Date: 2004-09-16T17:35:52
Editor: MichaelMcGrady <[EMAIL PROTECTED]>
Wiki: Apache Struts Wiki
Page: StrutsCatalogSimpleDispatchAction
URL: http://wiki.apache.org/struts/StrutsCatalogSimpleDispatchAction
no comment
Change Log:
------------------------------------------------------------------------------
@@ -179,9 +179,143 @@
'''Michael !McGrady'''
+'''Following a suggestion of Hubert Rabago, I have constructed a utility class
!DispatchUtil so that you can get the same result by using'''
+{{{
+return new !DispatchUtil.dispatch(this,mapping,form,request,response);
+}}}
+'''in your action execute class, and, of course, providing the related actions. That
class follows. Hubert is talking about putting something into !RequestUtils for
struts that does the same thing. Importantly, you can jettison all of
!DispatchAction, !LookupDispatchAction and !MappingDispatchAction if you use this.
You will have to change your action mapping struts-config.xml file for
!MappingDispatchAction (you can get rid of those multiple entries and just use one)
and will have to add .x where required in your submit, link and file buttons.'''
+
+{{{
+public class DispatchUtil {
+ protected static Log log =
LogFactory.getLog(DispatchUtil.class);
+ protected static MessageResources messages =
MessageResources.getMessageResources ("org.apache.struts.actions.LocalStrings");
+ protected HashMap methods = new HashMap();
+ protected Class[] types = { ActionMapping.class,
+ ActionForm.class,
+ HttpServletRequest.class,
+ HttpServletResponse.class };
+ public ActionForward dispatch(Action action,
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+ Class clazz = action.getClass();
+ String name = getMethodName(request,mapping);
+ if ("execute".equals(name) || "perform".equals(name)){
+ // Prevent recursive calls
+ String message = messages.getMessage("dispatch.recursive", mapping.getPath());
+ log.error(message);
+ throw new ServletException(message);
+ }
+ return dispatchMethod(action,clazz,mapping, form, request, response, name);
+ }
+
+ protected ActionForward dispatchMethod(Action action,
+ Class clazz,
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ String name)
+ throws Exception {
+ if (name == null) {
+ return this.unspecified(mapping, form, request, response);
+ }
+ Method method = null;
+ try {
+ method = getMethod(clazz,name);
+ } catch(NoSuchMethodException nsme) {
+ String message = messages.getMessage("dispatch.method", mapping.getPath(),
name);
+ log.error(message, nsme);
+ throw nsme;
+ }
+
+ ActionForward forward = null;
+
+ try {
+ Object args[] = {mapping, form, request, response};
+ forward = (ActionForward) method.invoke(action, args);
+ } catch(ClassCastException cce) {
+ String message = messages.getMessage("dispatch.return", mapping.getPath(),
name);
+ log.error(message, cce);
+ throw cce;
+ } catch(IllegalAccessException iae) {
+ String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
+ log.error(message, iae);
+ throw iae;
+ } catch(InvocationTargetException ite) {
+ Throwable t = ite.getTargetException();
+
+ if (t instanceof Exception) {
+ throw ((Exception) t);
+ } else {
+ String message = messages.getMessage("dispatch.error", mapping.getPath(),
name);
+ log.error(message, ite);
+ throw new ServletException(t);
+ }
+ }
+ return (forward);
+ }
+
+ protected static String getMethodName(HttpServletRequest request, ActionMapping
mapping) {
+ String methodName = null;
+ String buttonValue = null;
+ String parameter = mapping.getParameter();
+ if((parameter != null) && (parameter.endsWith(".x"))) {
+ methodName = parameter.substring(0,parameter.indexOf('.'));
+ } else {
+ Enumeration enum = request.getParameterNames();
+ while(enum.hasMoreElements()) {
+ buttonValue = (String)enum.nextElement();
+ if(buttonValue.endsWith(".x")) {
+ methodName = buttonValue.substring(0,buttonValue.indexOf(".x"));
+ }
+ }
+ }
+ return methodName;
+ }
+
+ protected Method getMethod(Class clazz,String name)
+ throws NoSuchMethodException {
+ synchronized(methods) {
+ Method method = (Method) methods.get(name);
+
+ if (method == null) {
+ method = clazz.getMethod(name, types);
+ methods.put(name, method);
+ }
+
+ return (method);
+ }
+ }
+
+ protected ActionForward unspecified(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+ String message = messages.getMessage( "dispatch.parameter", mapping.getPath(),
getMethodName(request,mapping));
+ log.error(message);
+ throw new ServletException(message);
+ }
+
+ protected ActionForward cancelled(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+ return null;
+ }
+}
+}}}
+
----
-Seems to me that most of the SimpleDispatchAction duplicates whats already in the
DispatchAction class. If we re-factored DispatchAction so that the parameter retrieval
was moved into a new getParameter() method then all that would be needed to achieve
what you want is a flavour that overrides the getParameter()/getMethodName() methods.
+Seems to me that most of the !SimpleDispatchAction duplicates whats already in the
!DispatchAction class. If we re-factored !DispatchAction so that the parameter
retrieval was moved into a new getParameter() method then all that would be needed to
achieve what you want is a flavour that overrides the getParameter()/getMethodName()
methods.
+
+
+
Something along the lines of ...
@@ -222,4 +356,9 @@
}}}
'''Niall Pemberton'''
+
+'''Thanks, Niall, HOWEVER -------
+This is fundametally mistaken, Niall, and rests on an important misconception. The
data and the logic of !SimpleDispatchAction differ from all of !DispatchAction,
!LookupDispatchAction, and !MappingDispatchAction. The error here is thinking that
just because they all get the name of the method to call that anything else is just a
mere difference in internal logic. That is not the case. Using one instead of the
other will break the code in lots of ways, and there are huge diffences between these
classes. None of the data used for the struts existing dispatch classes is used to
determine the method in the !SimpleDispatchAction.'''
+
+''Michael !McGrady'''
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]