How To Chain ActionSupport Classes In Struts2

Sometimes you may need to execute one ActionSupport class and then after that ActionSupport class completes successfully, you need to call another ActionSupport class that can further process the instance variables created by the first ActionSupport class. This type of work flow is called chaining ActionSupport classes. Struts2 supports chaining ActionSupport classes with the type="chain" result.

Example Application

In the example application (download an Eclipse - Maven archived dynamic web project) I have an ActionSupport class named PeopleGateway. This class has an instance field named contactList (an ArrayList of Person objects) that it creates and populates.

In the following Struts2 action (see struts.xml in the example application) the PeopleGateway class is called in response to the ViewContacts action. Upon success being returned by the class's execute method the viewcontacts.jsp is rendered. In viewcontacts.jsp I iterate over the contactList (which is now available on the valuestack) and list each Person object stored in the contactList collection.



<action name="ViewContacts" class="action.PeopleGateway">
<result name="success">/viewcontacts.jsp</result>
<result name="error">/error.jsp</result>
</action>

However, what if i also want to enable the use case of saving the contacts to a text file? How can I reuse the PeopleGateway ActionSupport class but then further process the contactList by creating and returning a text file to the user? Chaining the result of the PeopleGateway class to another class that will further process the instance variables exposed by the PeopleGateway class is the answer.

In the following Struts2 action (see struts.xml in the example application) the action SaveContacts is used to enable the use case of saving the contacts to a text file. This action initially calls the PeopleGateway ActionSupport class to get the contactList populated. Note the success result has type="chain". The will cause the SaveFile action to be called when success is returned by the PeopleGateway class's execute method.



<action name="SaveContacts" class="action.PeopleGateway">
<result name="success" type="chain">SaveFile</result>
<result name="error">/error.jsp</result>
</action>

<action name="SaveFile" class="action.TextFile">
<result name="success">/index.jsp</result>
<result name="error">/error.jsp</result>
</action>

The SaveFile action calls the TextFile ActionSupport class. The TextFile class also has an instance field named contactList. This instance field receives a copy of the contactList that belongs to PeopleGateway class, so the TextFile's contactList wil have all the same Person objects. In the TextFile class's execute method I just iterate over the contactList collection creating a String that has all the Person objects field values (eg firstName, lastName, etc). I then write that String back to the browser as a plain text file.

The key to chaining ActionSupport classes is to name the instance variables the same in both classes. Then the Struts2 framework will automatically copy the values of those instance variables from one ActionSupport class to another.

The beauty of using type="chain" is that I don't have to recreate in class TextFile the code that populates contactList. I continue to have only one place where contactList is populated. If later on I change how contactList gets all the Person objects (in my example I've hard-coded the creation of the Person objects) I only need to change my code in one place.

Also chaining ActionSupport classes enables me to keep each ActionSupport class focused on just one task. This keeps my ActionSupport classes smaller, easier to understand, and simpler to maintain.

References

Apache Struts2 Documentation, Chain Result

View working example application

Eclipse - Maven Example Application

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.002. Contact Blog Owner