Date: 2004-10-25T19:08:38 Editor: JoeGermuska <[EMAIL PROTECTED]> Wiki: Apache Struts Wiki Page: ActionChaining URL: http://wiki.apache.org/struts/ActionChaining
Remove long and old emai; attempt to summarize some recent list discussion. Change Log: ------------------------------------------------------------------------------ @@ -1,6 +1,10 @@ -Navigation Trail: HomePage / StrutsProjectPages / StrutsDeveloperPages / JamesMitchell / MailDocumentation +In a nutshell, '''Action Chaining''' is the practice of returning a non-redirect ActionForward which points to a Struts action path. This is chaining (where a redirect isn't) because it results in the ActionServlet triggering a second "run" through the RequestProcessor's processing flow. -Background: +Many developers find this an effective way to organize their web applications. However, it is important to note that this is not a supported way to use Struts. The RequestProcessor is designed with the assumption that it is executed once per HTTP request. Sometimes Action Chaining is used as a work around for an application which is not cleanly designed. + +An earlier author wrote on this page: + +{{{ One might argue that the normal flow of a Struts-based application would be similar to this: jsp -> /action -> jsp @@ -8,129 +12,9 @@ Some people (including myself) prefer this approach jsp -> /processaction -> /prepareviewaction -> jsp ----- -{{{ -On Tue, 23 Jul 2002, Pierre Delisle wrote: - -> Date: Tue, 23 Jul 2002 23:26:09 -0700 -> From: Pierre Delisle <[EMAIL PROTECTED]> -> Reply-To: Struts Developers List <[EMAIL PROTECTED]> -> To: [EMAIL PROTECTED] -> Subject: action calling another action -> -> I have a 1.0 struts-based web application where a "higher-level" -> action depends on the processing associated with another lower-level -> action. -> - -Welcome to the eternal debate over whether action chaining/nesting is a good design pattern or not :-). -I'm *not* a believer, but lets address your questions anyway. - -> For example, action "foo" needs to invoke the processing associated -> with action "bar". -> -> Using struts 1.0, I could do the following in the FooAction: -> -> ActionServletMine actionServlet = -> (ActionServletMine)mapping.getMappings().getServlet(); -> ActionMapping targetMapping = actionServlet.findMapping("/bar.do"); -> ((BarAction)actionServlet.getActionInstance( -> targetMapping)).perform(targetMapping, form, request, response); -> - -You should have been able to pass "/bar" as the argument to the -findMapping() method, even in Struts 1.0. - -> ActionServletMine is my own subclass of ActionServlet. It simply -> provides the extra method "getActionInstance()" to allow me to get -> access to the action instance associated with "targetMapping". (it -> calls processActionCreate()). -> -> Migrating to struts 1.1, I was hoping for backwards compatibility, but -> ActionMapping.getMappings() seems to have been removed without being -> first deprecated. Any reason, or am I missing something? (btw, I know -> I could simply call getServlet() within the Action subclass, but I'm -> still curious as to why getMappings() has been removed). -> - -There is no longer a single collection of ActionMappings -- there is one per application module. -So you'll need to do the following to get an -ActionMapping: - - ApplicationConfig appConfig = (ApplicationConfig) - request.getParameter(Action.APPLICATION_KEY); - ActionMapping mapping = (ActionMapping) - appConfig.findActionConfig("/bar"); - -> -> If I am to bite the bullet right now and rearchitect the webapp with -> the new struts 1.1 api, I still run into a few issues. -> -> What I've described above is how I thought would be the proper way to -> handle "action calling other action" in the very early days of 1.0. -> There might be a better approach now. If so, I'd appreciate if someone -> could point me in the right direction. -> - -Best practice is to factor the common code out and call it from both actions, so you don't -have to do any form of "chaining" or "nesting". - -> If I am to simply migrate the above code to the new 1.1 apis, it -> appears that I'd have to do the following: -> -> ActionServlet actionServlet = getServlet(); -> ApplicationConfig appConfig = mapping.getApplicationConfig(); -> RequestProcessor rp = actionServlet.getRequestProcessor(appConfig); -> -> It appears that "findMapping()" has been deprecated. So the code -> ActionMapping targetMapping = -> actionServlet.findMapping("/bar.do"); -> should be replaced by -> ActionConfig targetAction = appConfig.findActionConfig() -> - -You have to look up the correct ActionConfig from the ApplicationConfig, and cast -it to ActionMapping (for backwards compatibility). - -> The problem though is that the execute() method of an Action expects -> an ActionMapping object... which means that I'm back to want to use -> the old 1.0 api to get an ActionMapping (or I'm once again missing -> something). How come the new execute() method of Action does not take -> an ActionConfig object as argument instead of the old ActionMapping? -> - -The ActionMapping class in 1.1 is a subclass of ActionConfig, and that is the class -actually used in the configuration file parsing. So the cast will always work. - -> Finally, it would be preferable to migrate to the new RequestProcessor -> interface. However, ActionServlet.getRequestProcessor() is protected, -> preventing me from accessing it from my Action code. Any reason why it -> is not public? - -Because you shouldn't be messing around with this stuff in the first place :-). - -Actually, the RequestProcessor instance that is processing the current request can be -acquired directly, from the same place that ActionServlet gets it: - - String key = Action.REQUEST_PROCESSOR_KEY + appConfig.getPrefix(); - RequestProcessor processor = (RequestProcessor) - servlet.getServletContext().getAttribute(key); - -The only difference is that the ActionServlet.getRequestProcessor() method will lazilly -instantiate the request processor the first time. By the time you execute the above code -in an Action, you will not have to worry about that. - -> -> Many thanks for any answer/advice... -> -> -- Pierre -> - -Craig - - }}} - +}}} +so again, this is evidence that people use this method successfully. This topic has been discussed exhaustively on the StrutsUserMailingList. ---- @@ -157,4 +41,3 @@ directly to the business facade. -Ted. - --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]