Professional Documents
Culture Documents
Apache Struts (formerly under the Apache Jakarta Project, Struts is now a top level
project) is an open-source framework for developing Java EE web applications. It uses
and extends the Java Servlet API to encourage developers to adopt an MVC architecture.
It was originally created by Craig McClanahan and donated to the Apache Foundation in
May, 2000.
Contents
[hide]
• 4 External links
1
frameworks may also be another option to building complex web Form validations with
Struts in the future.
In December 2005, Struts joined forces with another popular J2EE framework,
WebWork. WebWork is being adopted as the 2.0 release of Apache Struts. WebWork spun
off from Struts several years ago, and offers many enhancements and refinements, while
retaining the same general architecture of the original Struts framework.
Sun recently brought out a new addition to the Java platform, called JavaServer Faces
(JSF). Aside from the original framework, the Apache Struts project also offers a JSF-
based framework called Shale.
Other MVC frameworks that are not J2EE based include Ruby on Rails, WebObjects,
Django, Catalyst, TurboGears and CakePHP.
See also
• Model-view-controller
• Jakarta
• Java EE
References
• James Holmes: Struts: The Complete Reference, McGraw-Hill Osborne Media,
ISBN 0-07-223131-9
• Bill Siggelkow: Jakarta Struts Cookbook, O'Reilly, ISBN 0-596-00771-X
• James Goodwill, Richard Hightower: Professional Jakarta Struts, Wrox Press,
ISBN 0-7645-4437-3
• John Carnell and Rob Harrop: Pro Jakarta Struts, Second Edition, Apress, ISBN
1-59059-228-X
• John Carnell, Jeff Linwood and Maciej Zawadzki: Professional Struts
Applications: Building Web Sites with Struts, ObjectRelationalBridge, Lucene,
and Velocity, Apress, ISBN 1-59059-255-7
• Ted Husted, etc: Struts in Action, Manning Publications Company, ISBN 1-
930110-50-2
• Struts View Assembly and Validation, (PDF format).
• Stephan Wiesner: Learning Jakarta Struts 1.2, Packt Publishing, 2005 ISBN 1-
904811-54-X
2
External links
• Apache Struts' home page
• AppFuse
• Struts Console : GUI tool for working with Struts
• Struts and UTF-8 : Handling UTF-8 in Struts with Servlet filters
• Struts-Layout : Rich TagLib for Struts
• Free chapter from Learning Jakarta Struts 1.2: A concise and practical tutorial
book (PDF format)
• A step-by-step Tutorial for Struts
• How to configure Struts for Tiles and modules
For JSP and J2EE developers looking for a way to manage the complexity of large web sites, the platform of choice has
been Struts. This framework, based on the Model-View-Controller design pattern and part of the Apache Jakarta
project, is in use throughout the industry. Struts combines tools for form validation, workflow control, and separation of
business logic from display.
After nearly a year of anticipation, Jakarta Struts 1.1 is finally out the door. In reality, however, this release is more like
Struts 1.99 or even Struts 2.0 when you get done looking at all the new features and functionality that have been added.
And now that 1.1 is complete, the developers and user community are looking toward the 1.x and 2.0 releases, with a
plethora of new features and integrations waiting in the wings. With that in mind, let's look at what's new in 1.1, and
what's upcoming in the next few months and year.
To begin with, the release is much more bulletproof than 1.0.2 was, mainly as a result of the thousands of developers
who have been using the 1.1 betas and finding bugs. In addition, the same developers were finding the shortcomings of
1.0 as they deployed Struts as their application framework, and have been adding some sorely needed features.
The following sections briefly describe a few of the key advances found in the Struts 1.1 release.
Navigation Improvements
In 1.1, you can have an action that forwards directly to a JSP page without needing to define an Action class. The
html:link tag can specify an action rather than a URI, allowing you to define links that pass through intermediate
Actions.
Dynaforms
Dynaforms allow you to define ActionForms directly from the struts-config.xml file, without needing to
create an explicit new class. As a result, it's easy to create a new form on the fly, without having to spend a lot of time
on bean properties.
Validator Framework
3
Hand in hand with Dynaforms, the validator framework allows you to define validation logic for forms using XML
descriptors rather than having to write a validate() method on an ActionForm. In addition to the predefined
validation (which includes length, type, and credit card checks), you can also define your own validations. You can also
define field validations that depend on the values of other fields.
Tiles Taglib
Tiles provides a very powerful templating framework that enables you to define common document struts (headers,
footers, sidebars) using either JSP documents or XML files. Using Tiles, you can essentially include document content
from another file, passing parameters into the document.
As the Java Standard Tag Library becomes more widely adopted, Struts has kept in step by offering tight integration.
For example, the struts-el taglib offers versions of most of the Struts tags that can have embedded Expression
Language (EL) values in them. For example, the following can generate a computed URL for an HTML link.:
<html-el:link href="${aBean.nextPage}">
Next Page
</html-el:link>
In addition, some of the base Struts tag libraries now have a better understanding of JSTL. For example, the "indexed"
property of the Struts HTML form tags can now be wrapped inside a JSTL <c:forEach> loop, as well as in a
Struts <logic:iterate> loop.
Looking ahead to the Java Server Faces framework, which will be released at the end of the year, Struts included a
contributed JSF integration tag library, which will enable developers to begin exploring JSF and working out migration
and integration strategies for this new Java Community Process Technology.
There have also been countless tweaks and minor improvements throughout the Struts framework—all designed to
improve the usability and reliability of the framework. The best place to look to see the full picture is the 1.1 release
notes.
The first thing people wonder about with Struts is how long it will take for a 1.2 release to appear. If you took the 1.0 to
1.1 timeframe as a guideline, you might be looking out into 2005 for a 1.2 release. However, the Struts development
team took a lesson from the 1.1 release (too many changes between releases means that it's hard to lock it down). So the
team plans to do many more frequent and focused releases.
The expectation is that 1.2 will release sometime in the next few months, with a few minor features that couldn't make
the feature freeze cutoff for 1.1, as well as a migration of some of the resource management code to the Jakarta
Commons libraries rather than the "proprietary" Struts versions. After that, there will be a release whenever there have
been more than a few bug fixes or new features added. So expect Struts to look more like Linux from now on, frequent
small releases.
4
Another thing to watch for is the eventual deprecation of the Struts tag libraries. The Struts taglibs largely date from
before JSTL was available, and most of their functionalities can be better served by the equivalent JSTL tags at this
point. As JSTL-compatible (Servlet 2.3) containers become the standard (such as Tomcat 4.0), there will be less and
less reason to use (and, by extension, to maintain and improve) the Struts tag libraries.
Eventually, Struts may find itself out of a job. As the JSF standard evolved over the last year, more and more of the
Struts functionality crept into JSF. This is not surprising, considering that Craig McClanahan, the "father" of Struts, is
also the JSF Spec Lead. Because JSF is a JCP technology, it will be widely adopted and may eventually push out Struts
because there is a lot of overlap between the two. Of course, the Struts development community is already busily
discussing how to keep Struts relevant in a post-JSF world, and you can also expect tools to provide cross-compatibility
and migration from Struts to JSF after JSF is available for production applications (again, in 2004.)
Two potential upgrades to Struts are being discussed. The first is the capability to use JSP pages as Actions, which
would let developers dynamically redefine Actions without having to recompile or restart the server (as well as letting
page authors create business logic using technologies like JSTL rather than pure Java). The other includes
improvements to automated type conversion so that after validation, values are made available to the business logic in
their native forms (Date, Integer, and so on) rather than as String. There are also ongoing active discussions of how
Struts can become more internationalization-friendly and work as a framework for web services.
Summary
With an increasing user community, more frequent releases, and the challenge of making Struts relevant in
light of JSF, you can expect a lot of new functionality in the post-1.1 Struts world.
Apache Struts
Apache Struts is a free open-source framework for creating Java web
applications.
5
handler provided by the application
developer.
• A location handler that transfers
control to another resource that
completes the response.
• A tag library that helps developers
create interactive form-based
applications.
The framework's architecture and tags are buzzword compliant. Struts works well with conventional
REST applications and with nouveau technologies like SOAP and AJAX.
The Apache Sruts Project offers two major versions of the Struts
framework. Struts 1 is recognized as the most popular web application
framework for Java. The 1.x framework is mature, well-documented,
and widely supported. Struts 1 is the best choice for teams who value
proven solutions.
For more about the future of Struts, see our Roadmap FAQ, especially
"What should I use with my next project?".
6
Kickstart FAQ
General
Product Support
Mailing Lists
General
7
I'm new to Apache Struts. How do I get started?
The best available release of Apache Struts is Struts 1.2.9. The Struts
1.2.9 release has its own area of the website. If you are new to Java
or web development, as well as Apache Struts, be sure to review the
Preface to the User Guide.
The main Struts web site covers the latest, unreleased version of each
major release series (Struts 1.3 and Struts 2.0). The documentation
for past releases are also available online. See the navigational menu
for links to the documentation for each release.
To learn more about using Apache Struts, you can also visit Struts
Central, which catalogs all the known resources about Apache Struts
for both Struts 1 and Struts 2. To keep up on the latest news about
"everything Struts", point your RSS reader at the Planet Struts news
site. If you still have questions, you can search the User Mailing List
archives, or post your own question to the list. (Plain old Google often
works too!)
Yes. The only requirements you must meet are those listed in the
Apache License.
8
Do I have to credit Apache Struts on my own web site?
For a listing of some Java and Struts ISPs, visit the Struts Community
Resources area on SourceForge.
Product Support
9
The Struts user mailing list is also very active, and welcomes posts
from new users. Before posting a new question, be sure to consult the
MAILING LIST ARCHIVE and the very excellent How To Ask Questions
The Smart Way by Eric Raymond. Please do be sure to turn off HTML in
your email client before posting.
We are grateful for any patches, and we welcome new ideas, but the
best way to see that something gets added to the framework is to do
as much of the work as you can, rather than rely on the "kindness of
strangers". Worst case, you can apply the patch to your copy of the
framework and still use the feature in your own application. (Which is
what open source is ~really~ all about.)
Mailing Lists
10
Yes. send a blank message to < user-digest-
subscribe@struts.apache.org >.
If you are subscribed to the digest, you can also post to the list. Just
be sure to send your post to the user list rather than trying to reply to
the digest.
Not a usenet group, but the Apache Struts User list can be accessed
with your favorite newsgroup reader from the GMane News Site.
Subscribe to groups gmane.comp.jakarta.struts.devel for the
developer list, or gmane.comp.jakarta.struts.user for the user list.
You must be subscribed to the user list or user digest before posting
(or use the GMane Newsgroups instead).
No. Each major version has it's own JIRA project, but we share the
mailing lists.
From the email account used to subscribe to the list, send a blank
message to < user-unsubscribe@struts.apache.org >.
11
If you are receiving the digest, you must send a blank email to < user-
unsubscribe@struts.apache.org > instead.
by Chuck Cavaness, author of Programming Jakarta Struts and the recently released Jakarta Struts Pocket
Reference
07/30/2003
The popularity of JSP Custom Tags has been rapidly growing since they were first introduced in the JSP 1.1
specification. The Struts framework, which was introduced in 2000, includes a set of Tag libraries that are
instrumental in harvesting the fruits of the Struts framework. This article looks at some of the ways to get
more out of those tags and helps make sense out of a few of the more complicated tasks.
We all should know by now that JSP Custom Tags were created to solve these problems and a few others.
They are easier to maintain because the logic is programmed in once place and the construction of web
applications is made simpler because a non-Java designer can drop them into a JSP and instantly see the
results. Most popular JSP editors such as DreamWeaver and WSAD support Custom Tag syntax and the
ability to step through them in a debugger.
The Tags themselves are built using Java, of course. Inserting a Tag only requires embedding an XML-like
fragment into a JSP. When a JSP that contains one or more tags is invoked, the servlet produced from JSP
compilation calls out to the appropriate Tag handler instance to perform its logic. All invocations of the
same Tag invoke the same code. The better application's containers will create a pool of tag instances and
not create a new instance of the Java class for every request. This helps to improve performance in a
manner similar to how an EJB container can reuse Stateless Session bean instances.
• Bean Tags
• HTML Tags
• Logic Tags
• Nested Tags
• Template Tags
• Tiles Tags
12
The Bean Tags
The Tags within the Bean Library are used for creating and accessing JavaBeans and a few other general
purpose uses. Although these tags work with any standard JavaBean, they are often used with Objects
that extend the Struts ActionForm class. Table 1 lists the tags within the Bean Library.
cookie Define a scripting variable based on the value(s) of the specified request cookie.
define Define a scripting variable based on the value(s) of the specified bean property.
header Define a scripting variable based on the value(s) of the specified request header.
include Load the response from a dynamic application request and make it available as a bean.
parameter Define a scripting variable based on the value(s) of the specified request parameter.
write Render the value of the specified bean property to the current JspWriter.
Two of the most often used Tags from Table 1 are the message and write Tags.
13
file Render a File Select Input Field
Most all of the Tags within the HTML Tag library must be nested within the Struts Form Tag.
14
Tag Name Description
Evaluate the nested body content of this tag if the requested variable is either null
empty
or an empty string.
Evaluate the nested body content of this tag if the requested variable is equal to
equal
the specified value.
forward Forward control to the page specified by the specified ActionForward entry.
Evaluate the nested body content of this tag if the requested variable is greater
greaterEqual
than or equal to the specified value.
Evaluate the nested body content of this tag if the requested variable is greater
greaterThan
than the specified value.
iterate Repeat the nested body content of this tag over a specified collection.
Evaluate the nested body content of this tag if the requested variable is greater
lessEqual
than or equal to the specified value.
Evaluate the nested body content of this tag if the requested variable is less than
lessThan
the specified value.
Evaluate the nested body content of this tag if the specified value is an
match
appropriate substring of the requested variable.
Generate the nested body content of this tag if the specified message is not
messagesNotPresent
present in this request.
Generate the nested body content of this tag if the specified message is present in
messagesPresent
this request.
Evaluate the nested body content of this tag if the requested variable is neither
notEmpty null, nor an empty string, nor an empty java.util.Collection (tested by the
.isEmpty() method on the java.util.Collection interface).
Evaluate the nested body content of this tag if the requested variable is not equal
notEqual
to the specified value.
Evaluate the nested body content of this tag if the specified value is not an
notMatch
appropriate substring of the requested variable.
Generate the nested body content of this tag if the specified value is not present
notPresent
in this request.
Generate the nested body content of this tag if the specified value is present in
present
this request.
15
The Nested Tags don't add any additional functionality over the Struts standard Tags other than to support
the nested approach. For each Tag in the Bean, HTML, and Logic libraries, there is an equivalent nested
Tag.
However, since the Tiles framework was introduced, the Template Tags have been deprecated and
developers are encouraged to use Tiles.
Add an element to the surrounding list. Equivalent to 'put', but for list
add
element.
get Gets the content from request scope that was put there by a put tag.
16
Figure 1. A Shopping Cart page showing multiple items
Using JSP without Struts, this functionality would most likely be accomplished with some rather
unattractive looking Java Scriptlets using loops. With the Struts Iterate Tag, it becomes somewhat
innocuous and much easier to manage over the lifetime of the application.
The following example code snippet shows what this might look like using the Iterate Tag from the Logic
library.
<logic:iterate id="cartItem" name="UserContainer" property="cart.items">
<!This Table Row will be repeated for each item in the user's cart >
17
<tr bgcolor="#ffffff">
<!Delete checkbox for item >
<td valign="top" align="middle">
<input
type="checkbox"
value="<bean:write name="cartItem" property="id"/>"
name="deleteCartItem">
</td>
<! name and description for item >
<td valign=top align=left>
<html:link
page="/action/viewitemdetail"
paramName="cartItem"
paramId="id"
paramProperty="id">
<! Write out the name of the Item >
<bean:write name="cartItem" property="name"/>
</html:link>
<br>In Stock Usually ships in 23 business days<br>
Available for pickup at most stores
</td>
<! Write out a Quantity Input Field >
<td valign="top" noWrap align="middle">
<input
type="text"
18
maxlength="3"
size="3"
name="qty_<bean:write name="cartItem" property="id"/>"
value="<bean:write name="cartItem" property="quantity"/>">
</td>
<! Unit price for item >
<td valign="top" noWrap align="middle">
$<bean:write name="cartItem" format="#,##0.00" property="unitPrice"/>
</td>
<! Extended price for item >
<td valign="top" align="right">
<table cellspacing="2" cellpadding="3" width="100%" border="0">
<tbody>
<tr>
<td align="right" bgcolor="#ffcc00">
$<bean:write
name="cartItem"
format="#,##0.00"
property="extendedPrice"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</logic:iterate>
19
Looking at this snippet from a JSP, you might be inclined to comment on how formidable it appears. You
should however quickly recognize that with the exception of a few Struts tags, most of the text is HTML;
which is how it should be.
Using collections is rather straightforward. However, if your data is for some reason stored within an
instance of a java.util.Map, getting at the properties in the map is a little trickier, but nonetheless
solvable with the Iterate Tag. Using the Iterate Tag, we can iterate through the Map and access each
element. Normally each Object that you iterate over is an element of the underlying collection, a
ShoppingCartBean, for example. However, when iterating over a Map instance, the Object is of type
java.util.Map.Entry.
• Key: The key under which the item is stored in the Map.
• Value: The value associated with the key.
Let's say you are using a Struts ActionForm (standard or a dynamic) and it contains a property named
"usermap" that is declared as a Map and instantiated as a java.util.HashMap. In this Map, the key is a
unique user ID and the value is a String representing the users encrypted password. Figure 2 illustrates
what this would look like.
The following code fragment shows an example of iterating through this Map and writing out the two
values.
<logic:iterate id="user" name="userForm" property="usermap">
<tr>
<td>User Id: <bean:write name=" user" property="key"/></td>
<td>Password: <bean:write name=" user" property="value"/></td>
</tr>
20
</logic:iterate>
As you can see from this JSP fragment, using the Iterate Tag with Maps is not much different than with
Collections. The primary distinction is that of using the key and value attributes to access the data stored
within the Map. Once you have references to this data, you can use it within the Iterate block just as you
would with anything else.
The Struts framework includes the ability to catch errors and populate an Errors collection that can be
accessed from within the JSPs. This is made even easier when using the Validator framework. Whether
you're doing programmatic or declarative validation, the Errors collection is inserted into the request and
available to a JSP. You can use either the Messages or the Errors Tag (depending on which type of
validation problems occurred) to access the messages to display to the users.
Both of the Messages and Errors Tags support an "id" attribute that is used to store the current error
while looping through the collection of problems. In a very simple approach you can use the following
within your JSP:
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
This fragment would print out each message from the problem collection inside an HTML list.
There's a header and footer entry that you can pull from the resource bundle, which allows you to provide
some text to the beginning and end of the errors respectively. The following fragment shows the usage of
the errors.header element.
<bean:message key="errors.header"/>
<ul>
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</ul><hr>
errors.header=<h3><font color="red">Validation Error</font></h3>You must
correct the following error(s) before proceeding.
21
If the message collection is empty however, you would still see the header text and therefore it's best to
check for the presence of messages before printing anything out:
<logic:messagesPresent>
<bean:message key="errors.header"/>
<ul>
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</ul><hr>
</logic:messagesPresent>
The Struts framework makes use of this by storing the Locale for a user in the HttpSession, which is
created the first time a request is received from a user. This functionality can be turned off in Struts, but
it's on by default.
Once the Locale is stored in the user's session, the framework can make decisions about which localization
is performed. For example, the Struts framework will chose a resource bundle that best matches the
user's Locale. This makes it somewhat easier to brand a site because localized text can be rendered
automatically be the framework.
Many of the Tags also support this I18N functionality. For example, the Message Tag within the Bean
Library uses the Locale to automatically pull text from the proper bundle. However, there are some
additional ways you can format text output. The Write Tag has a format attribute that you can use to
format currency in a particular format. Suppose that I wanted to display currency in the following manner:
X,XXX.XX
Which is specific to mostly U.S. markets, then I could use the Write Tag this way:
<bean:write
name="cartItem"
format="#,##0.00"
property="unitPrice"/>
Although this works, there's actually a more portable way of doing this to support multiple formats.
There's an attribute called formatKey on the Write Tag that will pull the format from the resource bundle.
The Tag entry would look like the following:
22
<bean:write
name="cartItem"
format="currencyFormat"
property="unitPrice"/>
And the resource bundle would need to have the following entry:
currencyFormat=#,##0.00
Doing it this way allows each resource bundle to specify a currency format specific to its Locale.
First, checkboxes indicate checked/unchecked on/off, or true/false, depending on how you look at it; it's a
binary condition. In the Java world, you would think this needs to be represented as a primitive boolean or
a class java.lang.Boolean. However, since all values are sent from the browser to the server as Strings,
this complicates things a bit. That means that something needs to convert the String "on" or "true" to its
Boolean equivalent.
The second non-obvious thing is how browsers treat checkboxes when updating the server. If a checkbox
is checked, then a value is sent to the server like name="on", where "name" is the name given to the
checkbox in the HTML form. Well, guess what is sent to the server when the checkbox isn't checked? You
would think name="off" or name="false", right? Actually nothing is sent. Therefore the application can
have a tough time understanding what's going on with the checkboxes on the pages.
The Struts Checkbox Tag renders an HTML checkbox and will automatically check or uncheck it depending
on the state of the Boolean value of the ActionForm associated with the page. You have to remember
that if the checkbox is unchecked by the user, no notification will be sent and you must take this into
account. (Hint: One of the easiest ways to think about this is if you don't receive a value, then it must be
unchecked!)
When you have a large number of related checkboxes, you should consider storing the values within an
array and use the Multibox Tag.
In order to standardize some of the more useful Tags, Sun and other participants created an initiative and
formalized the most commonly used Tags. This initiative was turned into JSR-52, which has now released
1.0. Java Standard Tag Library (or JSTL as it's known), provides a specification for four separate areas of
concern:
• Core
• XML Processing
• Internationalization
• Database
23
The specification also describes an expression language (EL) that is designed to simplify page
development. As you might imagine, there is some overlap with some of the Tags provided by the Struts
library. For example, looping, error handling, and conditional logic is provided by JSTL as well as Struts.
The question is "which set of tags should I use?" The answer is to use the JSTL Tags where possible. For
existing code, it's probably not worth the risk to change. However, for new JSPs you should be looking at
the JSTL for Tag functionality. Struts 1.1 even includes a version of the JSTL Tags based on the new
Expression Language. Something definitely to keep you eye on in future versions of Struts.
Chuck Cavaness is a graduate from Georgia Tech with degrees in computer engineering and computer
science. He has built Java-based enterprise systems in the healthcare, banking, and B2B sectors. He is
also the author of two O'Reilly books, Programming Jakarta Struts and Jakarta Struts Pocket Reference.
24