True to the Model-View-Controller design pattern, Struts applications have three
major components: a servlet controller, which is provided by Struts itself,
JSP pages (the "view"), and the application's business logic (or the
"model"). Let's step through how this all fits together.
The Struts controller servlet bundles and routes HTTP requests to other
objects in the framework, including JavaServer Pages and
org.apache.struts.action.Action
subclasses provided by the
Struts developer. When initialized, the controller parses a configuration
resource file. The configuration resource defines (among other things)
the org.apache.struts.action.ActionMapping
s for an application.
The controller uses these mappings to turn HTTP requests into application actions.
An ActionMapping will usually specify:
- a request path (or "URI"),
- the object type (Action subclass) to act upon the request,
- and other properties as needed.
The Action object can handle the request and respond
to the client (usually a Web browser), or indicate that control should be forwarded
elsewhere. For example, if a login succeeds, a login action may wish
to forward the request onto the mainMenu.
Action objects have access to the application's controller servlet, and so have access
to that servlet's methods. When forwarding control, an Action object can indirectly
forward one or more shared objects, including JavaBeans, by placing them in one
of the standard collections shared by Java servlets.
An Action object can create a shopping cart bean, add an item to the
cart, place the bean in the session collection, and then forward control to
another mapping. That mapping may use a JavaServer Page to display the contents of the user's cart.
Since each client has their own session, they will each also have their own
shopping cart. In a Struts application, most of the business logic can be
represented using JavaBeans. An Action can call the properties of a JavaBean
without knowing how it actually works. This encapsulates the business logic,
so that the Action can focus on error handling and where to forward control.
JavaBeans can also be used to manage input forms. A key problem in designing
Web applications is retaining and validating what a user has entered between
requests. With Struts, you can define your own set of form bean classes, by
subclassing org.apache.struts.action.ActionForm
, and easily store
the data for an input form in these form beans. The bean is saved in one of the
standard, shared context collections, so that it can be used by other objects,
especially an Action object.
The form bean can be used by a JSP to collect data from the user ... by an
Action object to validate the user-entered data ... and then by the JSP again to
re-populate the form fields. In the case of validation errors, Struts has a
shared mechanism for raising and displaying error messages.
A Struts form bean is declared in the configuration resource, defined in a Java
source file, and linked to an ActionMapping using a common property name. When
a request calls for an Action that uses a form bean, the controller servlet
either retrieves or creates the form bean, and passes it to the Action object.
The Action object can then check the contents of the form bean before its input
form is displayed, and also queue messages to be handled by the form. When
ready, the Action object can return control with a forwarding to its input
form, usually a JSP. The controller can then respond to the HTTP request and
direct the client to the JavaServer Page.
The Struts framework includes custom tags that can automatically populate
fields from a form bean. The only thing most JavaServer Pages need to know
about the rest of the framework is the proper field names and where to submit
the form. Components like the messages queued by the Action can be output
using a single custom tag. Other application-specific tags can also be defined
to hide implementation details from the JSPs.
The custom tags in the Struts framework are designed to use the
internationalization features built into the Java platform. All the field labels
and messages can be retrieved from a message resource, and Java can
automatically provide the correct resource for a client's country and language.
To provide messages for another language, simply add another resource file.
Internationalism aside, other benefits to this approach are consistent labeling
between forms, and the ability to review all labels and messages from a central
location.
For the simplest applications, an Action object may sometimes handle the business logic
associated with a request. However, in most cases, an Action object should
invoke another object, usually a JavaBean, to perform the actual business logic.
This lets the Action focus on error handling and control flow, rather than
business logic. To allow reuse on other platforms, business-logic JavaBeans should not refer to any Web
application objects. The Action object should translate needed details from the
HTTP request and pass those along to the business-logic beans as regular Java
variables.
In a database application, for example:
- A business-logic bean will connect to and query the database,
- The business-logic bean returns the result to the Action,
- The Action stores the result in a form bean in the request,
- The JavaServer Page displays the result in a HTML form.
Neither the Action nor the JSP need to know (or care) from where
the result comes. They just need to know how to package and display it.
The rest of this Users Guide explains the various Struts components in greater
detail. The Struts release also includes several Developer Guides covering
various aspects of the frameworks, along with sample applications,
the standard Javadoc API, and, of course, the complete source code!
Struts is distributed under the Apache Software Foundation license. The code
is copyrighted, but is free to use in any application. See the
ASF license for specifics.