Action Chaining First, we usually define "action chaining" as creating a "move" action by having a "copy" action forward to a "delete" action. Simply going from one action to another isn't a classic example of harmful chaining. The key point is whether only one action resolves the business use case.
Classic action chaining is considered harmful because it implies that the Actions have become a business facade. Any Action should be able to call facade.copy and facade.delete from a move Action. Better yet, the facade should provide a move method, and implement it any way it likes. We should not feel like we need to reuse multiple Action classes to solve one business use case. Struts 1 Actions were intended to be what Martin Fowler calls a "transaction script", where "move" is one transaction, not two. The design of Struts 1 made action chaining difficult because s1 repopulates the request on every forward. When people start to use the S1 actions as an API, they want to do things like change properites on an ActionForm, and are surprised when the framework resets their changes! The Struts 2 group does discourgage classic Action chaining, because it implies the business API is underdevelpoed. Albeit, we do provide a action chaining result that copies the properties from one Action to the next. The interceptor stack and result are processed for the chained action, but the request doesn't pass back through the container. * http://struts.apache.org/2.x/docs/action-chaining.html So you can set a flag on the copy action and have it picked up by the delete action. This is *not* considered an ideal practice, since coupling individual Action classes complicates the API, but it's there when people choose to use it. So, yes, Struts 2 has an elegant solution for action chaining, if you choose to use it. Control preparation As mentioned, Struts 2 solves the control population issue via the preparable interface. Another solution is to use the action tag to execute an Action in place. * http://cwiki.apache.org/confluence/display/WW/action One way to use this tag is to put a control on a "snippet" JSP that is rendered as a result of an Action that does nothing but create the object that populates the control. The action tag sets "executeresult=true", then control markup will be "included" into the page (like a tile), after the action executes. In effect, exectuteResult actions can be used like a tag that can run its own action before emitting the markup. Input.jsp <%@ taglib prefix="s" uri="/struts-tags" %> <s:form> <s:action name="languages" namespace="/ActionTag" executeResult="true"/> <s:action name="colors" namespace="/ActionTag" executeResult="true"/> <ssubmit/> </s::form> Languages.jsp <%@ taglib prefix="s" uri="/struts-tags" %> <s:select tooltip="Choose Your Favorite Language" label="Favorite Language" list="favoriteLanguages" name="favoriteLanguage" listKey="key" listValue="description" emptyOption="true" headerKey="None" headerValue="None"/> Languages.java (execute) public String execute() { favoriteLanguages.add(new Select.Language("EnglishKey", "English Language")); favoriteLanguages.add(new Select.Language("FrenchKey", "French Language")); favoriteLanguages.add(new Select.Language("SpanishKey", "Spanish Language")); return SUCCESS; } struts.xml (Input, Languages) <action name="Input"> <result type="plaintext">Input.jsp</result> </action> <action name="Languages" class="app.Languages"> <result>Languages.jsp</result> </action> The advantage being that the "Languages" action could be dropped in whereever the "Languages" control is needed, and that the Action for the form doesn't need to know how to populate the Languages control. Now, the Action is going to be hit every time the page is rendered, but so long as you are using a caching data access layer, like IBATIS or Hibernate, it will end up being a memory-to-memory transfer, rather than a database access. -Ted. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]