You are on page 1of 6

Best practices for Struts development http://www-128.ibm.

com/developerworks/web/library/wa-struts/

Best practices for Struts development


Optimize the Struts framework in your Web application development

Level: Introductory
Palaniyappan Thiagarajan (tpalaniy@in.ibm.com), Software Engineer, IBM Global Services India
Pagadala Suresh (pjsuresh@in.ibm.com), Software Engineer, IBM Global Services India
16 Jun 2004

Leverage your Web application development using the flexible Struts framework. Here, the
authors explore best practices that you can follow to optimize this open source and mature
framework. Learn to use standard, yet valuable, Struts components, including ActionForm,
Action class, and ActionErrors.

Struts: A brief introduction


Struts, an open source framework you can use to build Web applications, is based on the popular
Model-View-Controller (MVC2) design paradigm. The framework is built upon standard technologies like
Java Servlets, JavaBeans, ResourceBundles, and XML, and it provides flexible and extensible components.
Struts implements the Controller layer in the form of ActionServlet and recommends building the View
layer using JSP tag libraries. Struts also provides a wrapper around the Model layer through Action
classes. Figure 1 illustrates the Struts framework based on the Model-View-Controller design.

Figure 1. Struts and MVC

Overview of Struts components


First, we'll explain the Struts components in the context of best practices and the role each one plays in your
Web application development.
Action

Every Action of your application extends Struts' org.apache.struts.action.Action. These


Action classes provide an interface to the application's Model layer, acting as a wrapper around the
business logic. Each Action class must provide its case-specific implementation to the perform()
method. The perform() method always returns a value of type ActionForward.
ActionForm

Every ActionForm of your application extends Struts'


org.apache.struts.action.ActionForm. ActionForms are simple JavaBeans that
encapsulate and validate request parameters. To validate your request data, your ActionForm's
validate() method must give a case-specific implementation. ActionForms serve as a carrier of
request data to the Action class. A JSP object combines with a respective ActionForm to form your
application's View layer, where almost every form field of the JSP object maps to an attribute of the
corresponding ActionForm.

1 of 6 5/17/2006 5:57 AM
Best practices for Struts development http://www-128.ibm.com/developerworks/web/library/wa-struts/

JSP custom tag libraries

The JSP custom tag libraries are a collection of actions presented as tags. This is a powerful feature of the
JSP Specification 1.1; it allows you to separate presentation from other application tiers. The libraries are
easy to use and you can read them in XML-like fashion. You can easily maintain the JSP components by
minimizing the use of Java scriptlets in them. The JSP tags that Struts provides include HTML, logic, and
bean tags.
ActionErrors

You use ActionErrors to support exception handling. An ActionError traps and propagates an
application exception to the View layer. Each one is a collection of ActionError instances.
ActionErrors encapsulate error messages, while the </html:errors> in the Presentation layer
renders all error messages in the ActionError collection.

Best Practice 1. Reuse data across multiple ActionForms


Now that you are familiar with the Struts components, we will continue by showing you ways to get the most
out of the framework. First, Struts recommends that you associate every JSP object with an ActionForm,
which encapsulates data represented in the screen. You access the form data in the JSP object using
accessory methods found in ActionForm. Listing 1 shows the conventional use of ActionForm tag in
the View layer.

Listing 1. Using ActionForm in JSP

<html:form action="/bp1">

<html:text property="attrib1" />

</html:form >

The ActionForm called "BP1AForm" includes the attribute attrib1, as well as its getter and setter
methods. In the configuration file struts-config.xml, the action "/bp1" maps to bp1AForm using
the name attribute. This facilitates data display in the JSP.
To implement this best practice, Struts recommends you do two things:
1. Create a JavaBean (BP1BForm) with attributes that form an attribute subset in BP1AForm, along
with the attributes' getter and setter methods.
2. Replace the attributes in BP1AForm with the bean BP1BForm by associating the bean with
BP1AForm. Now you can access this attribute subset in BP1AForm through BP1BForm. Listing 2
shows you how.

Listing 2. Accessing form attributes in JSP

<html:form action="/bp1">

<bean:define name="bp1AForm" property="bp1BForm" id="bp1B"


type="com.ibm.dw.webarch.struts.BP1BForm" />

<html:text name="bp1B" property="subsetAtt1" />

</html:form >

Points to remember

2 of 6 5/17/2006 5:57 AM
Best practices for Struts development http://www-128.ibm.com/developerworks/web/library/wa-struts/

This practice's main advantage is that you can use it when you need multiple ActionForms to access a set
of attributes. When following this best practice, you'll want to keep in mind the following:
Struts implements the <bean:define/> tag.
When the code <%@ taglib uri="struts-bean.tld" prefix="bean" %> points to
struts-bean.tld, the <bean:define/> tag starts to work in the JSP components.
BP1AForm's validation framework, which extends ActionForm, must validate BP1BForm's data.
When creating Action classes in your application, instead of directly extending
org.apache.struts.action.Action, create an Action class (IntermediateAction) by
extending org.apache.struts.action.Action to handle common things in your application. All
other Action classes extend this IntermediateAction class.

Best Practice 2. Use Action class to handle requests


Typically when using the Struts framework, for every action the JSP component requests your application to
execute, the application must extend Struts' org.apache.struts.action.Action to create an
Action class. This individual Action class interfaces with the application's Model layer while processing
the request.
To implement this practice, Struts recommends you follow these steps:
1. Create an Action class, say BP2Action, by extending
org.apache.struts.action.Action.
2. Create all other Action classes in your Web application by extending BP2Action.
3. In BP2Action, create a method performTask(), as in public abstract ActionForward
performTask(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws
IOException, ServletException.
4. In BP2Action add one or more generic methods to the application, for example
serverSideValidate(). You can decide on the method's access modifier by considering the
following factors:
If all Action classes must implement this method, make it abstract.
If some Action classes will provide a case-specific implementation, declare the method
protected and give it a default implementation.
5. In BP2Action, declare method perform() as final. Invoke the above generic method, which must
always be called before processing the request. Now call the method performTask() created in
step 3.
6. In every Action class extending BP2Action, add method performTask() with a case-specific
implementation.
Advantages

This practice has two main advantages. First, it helps you avoid redundant code in every Action class of
your Web application. Second, it gives the application more control over generic tasks by centralizing the
behavior in one Action class.

Best Practice 3. Use ActionForm to work on session data


In a Struts-based Web application, each ActionForm extends
org.apache.struts.action.ActionForm. These ActionForms encapsulate page data and
provide a validation framework to validate request parameters.

3 of 6 5/17/2006 5:57 AM
Best practices for Struts development http://www-128.ibm.com/developerworks/web/library/wa-struts/

Most Web applications maintain data in session to make them available throughout the application. This best
practice addresses this Web application feature. It allows methods toSession() and fromSession()
to move session data to and from the form data. Thus, it addresses session data maintenance in a Web
application.
To adhere to this practice, follow these steps:
1. Create an abstract class named BP3Form by extending
org.apache.struts.action.ActionForm.
2. In BP3Form, add methods with access modifiers as in public abstract void
toSession(SessionData sessionData) and void fromSession(SessionData
sessionData).
3. In every ActionForm, extend BP3Form and implement the abstract methods in which the form data
is transported to and from the session.
4. The corresponding Action class may determine the order in which these methods are called. For
example, you could invoke method toSession() on the ActionForm just before
actionForward is determined.
When to use this practice

This practice is most useful when session data is maintained as a single object and/or every page manipulates
or uses session data.

Best Practice 4. Handle exceptions effectively


Conventionally, when an application exception occurs in an Action class, the exception is first logged.
Then the class creates an ActionError and stores it in the appropriate scope. This Action class then
forwards control to the appropriate ActionForward. Listing 3 shows how Action class handles
exceptions.

Listing 3. Exception handling in an Action class

try {
//Code in Action class
}
catch (ApplicationException e) {
//log exception
ActionErrors actionErrors = new ActionErrors();
ActionError actionError = new ActionError(e.getErrorCode());
actionErrors.add(ActionErrors.GLOBAL_ERROR, actionError);
saveErrors(request, actionErrors);
}

While conventional exception handling procedures save exception information in every Action class, best
practice 4 aims to avoid redundant code while handling exceptions.
To use this practice, Struts recommends following these steps:
1. Create an Action class, say BP4Action, by extending
org.apache.struts.action.Action.
2. Create all other Action classes in your Web application by extending BP4Action.
3. In BP4Action, declare variable ActionErrors actionErrors = new
ActionErrors();.
4. In BP4Action, create a method performTask() as in public abstract ActionForward
performTask(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response,
ActionErrors actionErrors) throws IOException, ServletException.

4 of 6 5/17/2006 5:57 AM
Best practices for Struts development http://www-128.ibm.com/developerworks/web/library/wa-struts/

5. In BP4Action, declare method perform() as final. Then invoke generic methods, which must
always be called before processing the request. Now you can call the method performTask()
created in the previous step.
6. While implementing method performTask() in every Action class (by extending BP4Action),
handle application exceptions as shown in Listing 4.

Listing 4. Using ActionErrors effectively

try {
//Code in Action class
}
catch(ApplicationException appException) {
//Log exception
//Add error to actionErrors
actionErrors.add(ActionErrors.GLOBAL_ERROR,
new ActionError(appException.getErrorCode()));
}

In BP4Action, after invoking the method performTask(), save the ActionErrors using
saveErrors(request, errors).
Advantages

This practice's main advantage is that it avoids code redundancy in every Action class that handles
ActionErrors.

In conclusion
Building an easily maintainable Web application can be one of the most challenging tasks for a development
team. Using a mature framework like Struts helps you implement the infrastructure code normally associated
with building an application. The Struts framework provides a set of standard interfaces for plugging
business logic into the application, a consistent mechanism across development teams for performing tasks
such as user data validation, screen navigation, and so forth, as well as a set of custom tag libraries to
simplify developing screens.
These four best practices are important for you to extract more from the framework's features. You, as a
developer, can benefit from these lessons to increase your code modularity and application reusability, plus
minimize code redundancy. These are all critical to building an extensible Web application.

Resources
Find out more about Struts at the Jakarta Struts Home page.

Download the Struts source code.

Read "Struts, An Open-Source MVC Implementation" for an introduction to Struts (developerWorks,


February 2001).

Discover the "Struts Adoption" discussion of pertinent Struts issues.

Explore a useful reference on Struts, Mastering Jakarta Struts by James Goodwill (Wiley Publishers,
2002).

5 of 6 5/17/2006 5:57 AM
Best practices for Struts development http://www-128.ibm.com/developerworks/web/library/wa-struts/

Read about changes to Struts, including the Tiles library in "Struts and tiles aid component-based
development" (developerWorks, June 2002).

Browse for books on these and other technical topics.

Visit developerWorks Web Architecture and Java technology zones for a range of articles on the topics
of Web architecture, usability, and Java.

About the authors

Palaniyappan Thiagarajan specializes in Web application development using Struts framework and IBM
JADE framework. He has presented topics on the Struts framework in technical forums, and holds
professional certifications from IBM in IBM WebSphere Application Server 3.5, IBM DB2 Family
Fundamentals and IBM Certification for OOAD and UML. He has also written articles for IBM
developerWorks, Java zone.

Pagadala Suresh specializes in Java technology, WebSphere Application Server, and WebSphere
Studio Application Developer (WSAD), Ariba Buyer. He has participated in the IBM Redbook
program on WebSphere, and has professional experience in WebSphere Business Components
Composer and IBM JADE Framework.

6 of 6 5/17/2006 5:57 AM

You might also like