Struts User's Guide
Quick Links
Home
Table of Contents
Introduction
Model Components
View Components
Controller Components
Resources
Who We Are
1. Introduction
1.0 Prerequisites

This User Guide is written for active Web developers, and assumes a working knowledge about how Java Web applications work. Before getting started, you should understand the basics of these core technologies:

If you've created Web applications on other platforms, you can probably follow along, and then visit the above references as needed. These are core technologies that will be used in nearly all Java Web development projects.

1.1 Preface: Forward into the Past! (or a brief history of Struts)

When Java servlets were first invented, many programmers quickly realized that they were a Good Thing. They were faster and more powerful that standard CGI, portable, and infinitely extensible.

But writing HTML to send to the browser in endless println() statements was tiresome and problematic. The answer to that was JavaServer Pages, which turned servlet writing inside-out. Now developers could easily mix HTML with Java code, and have all the advantages of servlets. The sky was the limit!

Java web applications quickly became "JSP-centric". This in-and-of itself was not a Bad Thing, but it did little to resolve flow control issues and other problems endemic to web applications.

Another model was clearly needed ...

Many clever developers realized that JavaServer Pages AND servlets could be used together to deploy web applications. The servlets could help with the control-flow, and the JSPs could focus on the nasty business of writing HTML. In due course, using JSPs and servlets together became known as Model 2 (where using JSPs alone was Model 1).

Of course, there is nothing new under the Sun ... and many have been quick to point out that JSP's Model 2 follows SmallTalk's classic Model-View-Controller design pattern. It is now commonplace to use the terms Model 2 and MVC interchangeably.

The Struts project was launched in May 2000 by Craig R. McClanahan to provide a standard MVC framework to the Java community. In July 2001, Struts 1.0 was released, and IOHO, Java Model 2 development will never be quite the same.

1.2 The Model-View-Controller ('MVC') Design Pattern

In the MVC design pattern, application flow is mediated by a central Controller. The Controller delegates requests - in our case, HTTP requests - to an appropriate handler. The handlers are tied to a Model, and each handler acts as an adapter between the request and the Model. The Model represents, or encapsulates, an application's business logic or state. Control is usually then forwarded back through the Controller to the appropriate View. The forwarding can be determined by consulting a set of mappings, usually loaded from a database or configuration file. This provides a loose coupling between the View and Model, which can make an application significantly easier to create and maintain.

1.3 Struts Framework Overview

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.ActionMappings 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.

1.4 The Model: System State and Business Logic JavaBeans

The Model portion of an MVC-based system can be subdivided into concepts -- the internal state of the system, and the actions that can be taken to change that state. In grammatical terms, we might think about state information as nouns (things) and actions as verbs (changes to the state of those things).

Generally, your application will represent the internal state of the system as a set of one or more JavaBeans, with properties that represent the details of the state. Depending on your application's complexity, these beans may be self contained (and know how to save their state information persistently somehow), or they may be facades that know how to retrieve information from external sources (such as a database) when it is requested. Entity Enterprise JavaBeans (Entity EJBs) are also commonly used to represent internal state.

Large-scale applications will often represent the set of possible business logic actions as methods that can be called on the beans maintaining the state information. For example, you might have a shopping cart bean, stored in session scope for each current user, with properties that represent the current set of items that the user has decided to purchase. This bean might also have a checkOut() method that authorizes the user's credit card, and sends the order to the warehouse to be picked and shipped. Other systems will represent the available actions separately, perhaps as Session Enterprise JavaBeans (Session EJBs).

In some smaller scale applications, on the other hand, the available actions might be embedded within the Action classes that are part of the Controller role. This is appropriate when the logic is very simple, or where reuse of the business logic in other environments is not contemplated. The Struts framework supports any of these approaches, but strongly recommends separating the business logic ("how it's done") from the role that Action classes play ("what to do").

1.5 The View: JSP Pages and Presentation Components

The View portion of a Struts-based application is generally constructed using JavaServer Pages (JSP) technology. JSP pages can contain static HTML (or XML) text called "template text", plus the ability to insert dynamic content based on the interpretation (at page request time) of special action tags. The JSP environment includes a set of standard action tags, such as <jsp:useBean> whose purpose is described in the JavaServer Pages Specification. In addition, there is a standard facility to define your own tags, which are organized into "custom tag libraries."

Struts includes an extensive custom tag library that facilitates creating user interfaces that are fully internationalized, and that interact gracefully with ActionForm beans that are part of the Model portion of the system. The use of these tags is discussed in detail later.

In addition to JSP pages and the action and custom tags they contain, it is often necessary for business objects to be able to render themselves in HTML (or XML), based on their current state at request time. The rendered output from such objects can be easily included in a resulting JSP page by using the <jsp:include> standard action tag.

1.6 The Controller: ActionServlet and ActionMapping

The Controller portion of the application is focused on receiving requests from the client (typically a user running a web browser), deciding what business logic function is to be performed, and then delegating responsibility for producing the next phase of the user interface to an appropriate View component. In Struts, the primary component of the Controller is a servlet of class ActionServlet. This servlet is configured by defining a set of ActionMappings. An ActionMapping defines a path that is matched against the request URI of the incoming request, and usually specifies the fully qualified class name of an Action class. All Actions are subclassed from org.apache.struts.action.Action. Actions encapsulate the business logic, interpret the outcome, and ultimately dispatch control to the appropriate View component to create the response.

Struts also supports the ability to use ActionMapping classes that have additional properties beyond the standard ones required to operate the framework. This allows you to store additional information specific to your application, but still utilize the remaining features of the framework. In addition, Struts lets you define logical "names" to which control should be forwarded so that an action method can ask for the "Main Menu" page (for example), without knowing what the actual name of the corresponding JSP page is. These features greatly assist you in separating the control logic (what to do) with the view logic (how it's rendered).

Next: Building Model Components


Copyright (c) 2000-2002, Apache Software Foundation