Buy this Book
Print Book $44.95 Read it Now!
Print Book £31.95
Add to UK Cart
Reprint Licensing
Programming Jakarta Struts
Programming Jakarta Struts, Second Edition

By Chuck Cavaness
Price: $44.95 USD
£31.95 GBP

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Introduction
The Struts open source framework was created to make it easier for developers to build web applications based on the Java Servlet and JavaServer Pages (JSP) technologies. Like a building, a web application must have a solid foundation from which the rest of the structure can grow. The Struts framework provides developers with a unified infrastructure upon which Internet applications can be based. Using Struts as the foundation allows developers to concentrate on building the business application rather than on the infrastructure.
The Struts framework was created by Craig R. McClanahan and donated to the Apache Software Foundation (ASF) in 2000. The project now has several committers from around the world, and many developers are contributing to the overall good of the framework. The Struts framework is one of many well-known and successful Apache Jakarta projects. Others include Ant, log4j, and Tomcat. The overall mission of the Jakarta project is to provide commercial-quality server solutions, based on the Java platform, in an open and cooperative fashion.
No book on web technology would be complete without a brief look at how the World Wide Web (WWW) has become as popular as it is today. The Web has come a long way since the days when the first hypertext documents were sent over the Internet. In 1989, when the physicists at the CERN laboratory proposed the idea of sharing research information between researchers using hypertext documents, they had no idea how big the Web would grow or how essential it would become to daily life for much of the industrialized world. The Web is now an accepted part of our vernacular.
It took a while for the benefits of using the Web to become clear to others outside of CERN, but as we all know, it eventually erupted into what we use today. From its beginnings, the Web was designed for dealing with static documents, but it was a natural progression to want the ability to generate document content dynamically. The Common Gateway Interface (CGI) was created to do that very thing. CGI is a standard that allows web servers to interact with external applications in such a way that hypertext pages no longer have to be static. A CGI program can retrieve results from a database and insert those results as a table in a hypertext document. Likewise, data entered into a hypertext page can be inserted into the database. This technology opened up infinite possibilities and, in fact, started the Internet craze of the mid-1990s and today.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
A Brief History of the Web
No book on web technology would be complete without a brief look at how the World Wide Web (WWW) has become as popular as it is today. The Web has come a long way since the days when the first hypertext documents were sent over the Internet. In 1989, when the physicists at the CERN laboratory proposed the idea of sharing research information between researchers using hypertext documents, they had no idea how big the Web would grow or how essential it would become to daily life for much of the industrialized world. The Web is now an accepted part of our vernacular.
It took a while for the benefits of using the Web to become clear to others outside of CERN, but as we all know, it eventually erupted into what we use today. From its beginnings, the Web was designed for dealing with static documents, but it was a natural progression to want the ability to generate document content dynamically. The Common Gateway Interface (CGI) was created to do that very thing. CGI is a standard that allows web servers to interact with external applications in such a way that hypertext pages no longer have to be static. A CGI program can retrieve results from a database and insert those results as a table in a hypertext document. Likewise, data entered into a hypertext page can be inserted into the database. This technology opened up infinite possibilities and, in fact, started the Internet craze of the mid-1990s and today.
Although CGI applications are very good at what they do, there are some serious limitations to this approach. For one thing, CGI applications are very resource-intensive. A new operating system (OS) heavyweight process is created to handle every request that comes from a browser. Once the CGI script is finished executing, the process has to be reclaimed by the OS. This constant starting and stopping of heavyweight processes is terribly inefficient. You can imagine how bad the response time might be if hundreds of concurrent users were making requests to the same web application. Another major limitation of CGI is that it's difficult to link to other stages of request processing, because it is running in a separate process from the web server. This makes it difficult to handle things such as authorization, workflow, and logging.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Are Java Servlets?
Java servlets have become the mainstay for extending and enhancing web applications using the Java platform. They provide a component-based, platform-independent method for building web applications. Servlets don't suffer from the same performance limitations that standard CGI applications incur. Servlets are more efficient than the standard CGI threading model because they create a single heavyweight process and allow each user request to use a much more lightweight thread, which is maintained by the Java Virtual Machine (JVM), to fulfill the request. Multiple user requests can be threaded through the same instance of a servlet. A servlet is mapped to one or more uniform resource locators (URLs), and when the server receives a request to one of the servlet URLs, the service method in the servlet is invoked and it responds. Because each user request is associated with a separate thread, multiple threads or users can invoke the service method at the same time. This multithreaded nature of servlets is one of the main reasons that they are more scalable than standard CGI applications. Also, because servlets are written in Java, they are not proprietary to a platform or OS.
Another significant advantage of being written in the Java language is that servlets are able to exploit the entire suite of Java application programming interfaces (APIs), including Java DataBase Connectivity™ (JDBC) and Enterprise JavaBeans (EJB). This was one of the factors in servlets becoming part of the mainstream so quickly; there already was a rich Java library in place for them to leverage.
Servlets are not executed directly by a web server. They require a servlet container, sometimes referred to as a servlet engine, to host the servlet. This servlet container is loosely coupled to a particular instance of a web server, and together they cooperate to service requests. Figure 1-1 illustrates how a web server and servlet container cooperate to service a request from a web browser.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
JavaServer Pages
The first thing to understand about JavaServer Pages is that it's a natural extension to the Java Servlet technology. In fact, after some preprocessing by a translator, JSP pages end up being nothing more than Java servlets. This is a point that many beginning developers have a hard time understanding. JSP pages are text documents that have a .jsp extension and contain a combination of static HTML and XML-like tags and scriptlets. The tags and scriptlets encapsulate the logic that generates the content for the pages. The .jsp files are preprocessed and turned into .java files. At this point, a Java compiler compiles the source and creates a .class file that can be executed by a servlet container.
The translator that turns the .jsp file into a .java file takes care of the tedious work of creating a Java servlet from the JSP page. Figure 1-2 illustrates how a JSP page is translated and compiled into a servlet.
Figure 1-2: A JSP page is translated and compiled into a Java servlet
JSP technology has become an extremely popular solution for building web applications using the Java platform. JSP offers several advantages over its competitors:
  • JSP is a specification, not a product. Developers are able to choose a "best of breed" approach.
  • JSP pages are compiled, not interpreted, which can lead to better performance.
  • JSP pages support both scripting and access to the full Java language and can be extended through the use of custom tags.
  • JSP pages share the Write Once, Run Anywhere™ characteristics of Java technology.
As mentioned in the previous section, one of the limitations of using hardcoded HTML inside of servlets is the problem of separating page design and application logic programming responsibilities. This separation is easier with JSP pages, because the HTML designers are free to create web pages with whatever tools they choose (many of today's popular tools are capable of working with JSP and custom tags). When they are comfortable with the page layout, the JSP developers can insert JSP scriptlets and custom tags and save the files with a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
JSP Model 1 and Model 2 Architectures
The early JSP specifications presented two approaches for building web applications using JSP technology. These two approaches were the JSP Model 1 and Model 2 architectures. Although these terms are no longer used in the JSP specification, they still are widely used throughout the web tier development community.
The two JSP architectures differ in several key areas. The major difference is in how and by which component the processing of a request is handled. With the Model 1 architecture, the JSP page handles all of the processing of the request and is responsible for displaying the output to the client. This is illustrated in Figure 1-3.
Figure 1-3: JSP Model 1 architecture
Notice that there is no servlet involved in the process. The client request is sent directly to a JSP page, which may communicate with JavaBeans or other services, but ultimately the JSP page selects the next page for the client. The next view is determined based on either the JSP selected or parameters within the client's request.
In contrast, in the Model 2 architecture, the client request is first intercepted by a servlet, commonly referred to as a controller servlet. This servlet handles the initial processing of the request and determines which JSP page to display next. This approach is illustrated in Figure 1-4.
Figure 1-4: JSP Model 2 architecture
As shown in the figure, a client never sends a request directly to a JSP page in the Model 2 architecture. This allows the servlet to perform front-end processing, including authentication and authorization, centralized logging, and help with internationalization. Once request processing has completed, the servlet directs the request to the appropriate JSP page. How the next page is determined varies widely across different applications. For example, in simpler applications, the next JSP page to display may be hardcoded in the servlet based on the request, parameters, and current application state. In more sophisticated web applications, a workflow/rules engine might possibly be used.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Why Is Model-View-Controller So Important?
The MVC architectural pattern is not directly related to web applications or Java for that matter. In fact, it's quite common in Smalltalk applications, which generally have nothing to do with the Web.
As we saw in the previous section, the Model 2 approach is concerned with separating responsibilities in web applications. Allowing a JSP page to handle the responsibilities of receiving the request, executing some business logic, and then determining the next view to display can make for an unattractive JSP page, not to mention the maintenance and extensibility problems this entanglement causes. Application development and maintenance are much easier if the different components of a web application have clear and distinct responsibilities.
The MVC pattern is categorized as a design pattern in many software design books. Although there is much disagreement on the precise definition of the pattern, there are some fundamental ideas.
The MVC pattern has three key components:
Model
Responsible for the business domain state knowledge
View
Responsible for a presentation view of the business domain
Controller
Responsible for controlling the flow and state of the user input
With the MVC pattern, a form of event notification usually takes place to notify the view when some portion of the model changes. However, because a browser in a typical web application has a stateless connection, the notification from the model to the view cannot occur easily. Of course, an application could perform some type of push mechanism to push notification or data all the way to a client, but this is overkill for most web applications. A user can close the browser at any time, and generally no notification is sent to the server. A great deal of overhead is necessary to manage remote clients from the server side. This type of behavior is not necessary for typical web applications.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Is a Framework?
I have been using the term framework in this chapter without having defined what exactly it is, or how it adds value in software development. In its simplest form, a framework is a set of classes and interfaces that cooperate to solve a specific type of software problem. A framework has the following characteristics:
  • A framework comprises multiple classes or components, each of which may provide an abstraction of some particular concept.
  • The framework defines how these abstractions work together to solve a problem.
  • Framework components are reusable.
  • A framework organizes patterns at a higher level.
A good framework should provide generic behavior that many different types of applications can make use of.
There are many interpretations of what constitutes a framework. Some might consider the classes and interfaces provided by the Java language a framework, but these are really a library. There's a subtle, but very important, difference between a software library and a framework. A software library contains functions or routines that your application can invoke. A framework, on the other hand, provides generic, cooperative components that your application extends to provide a particular set of functions. The places where the framework can be extended are known as extension points. A framework commonly is referred to as an "upside-down" library because of the alternate manner in which it operates. Figure 1-5 illustrates the subtle differences between frameworks and software libraries.
Figure 1-5: A framework and a library are not the same thing
The Struts framework was created by Craig R. McClanahan and donated to the ASF in 2000. Craig is deeply involved in the expert groups for the Servlet and JSP specifications and wrote a large portion of the Tomcat implementation. He also speaks at various conferences, including JavaOne and ApacheCon.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Alternatives to Struts
Although this book is dedicated to the Jakarta Struts framework, Struts is far from the only Java Web framework available. There are quite a few available, each with their own proponents and evangelists.
Because framework versions and features may change with each new release, it's not always practical to compare and contrast Struts simply by reading these descriptions; you should conduct your own research with the latest stable versions of framework alternatives. This list is by no means exhaustive, but it will provide you with a launching pad.
Note that only solutions based on or around the Java platform are listed here. Microsoft also offers a competing technology based on Active Server Pages (ASP). Although the goal of ASP is similar to that of JSP, ASP and ASP+ are not discussed here—they're better left for a book on JSP and servlets. Furthermore, the Struts framework goes well beyond what is offered by JSP alone, and comparing ASP or other technologies similar to Struts wouldn't make sense.
Microsoft also has also introduced an "Application Block" called User Interface Process (UIP). UIP shares some of the same goals as MVC frameworks like Struts, but is meant for use with for the .NET programming model. Although interesting, it won't be presented here either.
At first, it might seem strange to include building your own framework as an alternative to using Struts. Why would you want to build frameworks from scratch when they already exist in readily-available products? The answer is the same reason that other open source or commercial products are developed. The available selection of products just might not be close enough to your desired framework, and it might be preferable to build it in-house.
The best advice I can give regarding building your own framework is to ask yourself several questions:
  1. Have I taken the time to inspect what's available and build a prototype using an available framework?
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Inside the Web Tier
This chapter discusses the relationship between the architectural tiers and their roles in an application. Special attention is given to the web tier, which allows an application to communicate and interoperate with clients over the Web. In particular, this chapter focuses on the physical and logical aspects of designing and using a web tier for your applications.
The Struts framework is based on the Java Servlet technology and, to a lesser extent, JavaServer Pages, and therefore is dependent on a web container. For Struts developers, understanding how the web container processes client requests is fundamental to a deeper understanding of the framework itself. This chapter illustrates the various components that are part of the web container and discusses each component's responsibilities.
This section presents a high-level architectural view of a Struts application. Although this section shows an architecture for an enterprise application, not all applications written using Struts will be of this size and makeup. However, this type of application does allow us to present many facets of how Struts applications may be configured.
Many applications—especially J2EE applications—can be described in terms of their tiers. The application's functionality is separated across these tiers, or functional layers, to provide separation of responsibility, reusability, improved scalability, and many other benefits. The separation of tiers may be a physical separation where each is located on a separate hardware resource, or it may be purely logical. In the latter case, one or more tiers are collocated (i.e., arranged or grouped together) on the same hardware resource, and the separation exists in terms of software components. Figure 2-1 illustrates the tiers that may be used by a typical Struts application.
Figure 2-1: Functional application tiers
Not every Struts application will contain all of the tiers illustrated in Figure 2-1. For many smaller applications, the middle tier may consist primarily of a web container that interacts directly with a database in the enterprise information system (EIS) tier.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
An Architecture Overview
This section presents a high-level architectural view of a Struts application. Although this section shows an architecture for an enterprise application, not all applications written using Struts will be of this size and makeup. However, this type of application does allow us to present many facets of how Struts applications may be configured.
Many applications—especially J2EE applications—can be described in terms of their tiers. The application's functionality is separated across these tiers, or functional layers, to provide separation of responsibility, reusability, improved scalability, and many other benefits. The separation of tiers may be a physical separation where each is located on a separate hardware resource, or it may be purely logical. In the latter case, one or more tiers are collocated (i.e., arranged or grouped together) on the same hardware resource, and the separation exists in terms of software components. Figure 2-1 illustrates the tiers that may be used by a typical Struts application.
Figure 2-1: Functional application tiers
Not every Struts application will contain all of the tiers illustrated in Figure 2-1. For many smaller applications, the middle tier may consist primarily of a web container that interacts directly with a database in the enterprise information system (EIS) tier.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The HTTP Request/Response Phase
To better illustrate how the web server and servlet container work together to service clients, this section discusses the protocol for an HTTP request and response, from the time a client request is received until the server returns a response. Struts makes heavy use of the request and response objects, and a complete understanding of the round-trip process will help clarify some topics discussed later in the book.
Although the browser is not the only type of client that can be used with Struts, it certainly is the most common. More and more developers are starting to use Struts for wireless applications and even some interaction with web services, but the web browser remains the predominant client.
HTTP is based on a request/response model, so there are two types of HTTP messages: the request and the response. The browser opens a connection to a server and makes a request. The server processes the client's request and returns a response. Figure 2-3 illustrates this process.
Figure 2-3: The HTTP request/response model
Both types of messages consist of a start line, zero or more header fields, and an empty line that indicates the end of the message headers. Both message types also may contain an optional message body.
The format and makeup of the request and response messages are very similar, but there are a few differences. We'll discuss each type of message separately.
The start line of an HTTP request is known as the request line. It's always the first line of the request message, and it contains three separate fields:
  • An HTTP method
  • A universal resource identifier (URI)
  • An HTTP protocol version
Although there are several HTTP methods for retrieving data from a server, the two used most often are
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Struts and Scope
The Struts framework uses various shared resource areas to store objects. The shared resource areas all have a lifetime and visibility rule that defines the scope of the resource. This section discusses these resources, their scopes, and how the framework uses them.
Each time a client issues an HTTP request, the server creates an object that implements the javax.servlet.http.HttpServletRequest interface. Among other things, this object contains a collection of key/value attribute pairs that can be used to store objects for the lifetime of the request. The key of each pair is a String, and the value can be any type of Object. The methods to store objects in and retrieve them from the request scope are:
public void setAttribute( String name, Object obj );
public Object getAttribute( String name );
Request-scope attributes can be removed using the removeAttribute() method; however, because the scope of the attribute is only for the lifetime of the request, it is not as important to remove them as it is for other scoped attributes. Once the server fulfills a request and a response is returned to the client, the request and its attributes are no longer available to the client and can be garbage-collected by the JVM.
The Struts framework provides the ability to store JavaBeans in a request, so that they can be used by presentation components such as JSP pages. This makes it much easier to access JavaBeans data, without having to do a manual cleanup of the objects later. There's seldom a need to remove objects from request scope; the web container takes care of it for you. Objects stored at the request level are visible only to resources that have access to that request. Once the response has been returned to the client, the visibility is gone. Objects that are stored in one request are not visible to any other client request.
The next-higher level of visibility is session scope. The web container creates an object that implements the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using URL Parameters
URL parameters are strings that are sent to the server with the client request. The parameters are inserted into the HttpServletRequest object from the URI query string and data that is sent in a POST method. The parameters are formatted as key/value pairs and are accessed by applications as request parameters. URL parameters play an important role in all web applications, and the Struts framework is no exception.
Don't get request parameters confused with request attributes. Attributes are objects that typically are inserted into the request so that they can be made available to other servlets, such as JSP pages.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Forward Versus Redirect
It's often necessary for more than one component to share control of a request. For example, one servlet may be responsible for authenticating and authorizing a client, while it's the job of a different servlet to retrieve some data for the user. The sharing of a request can be accomplished in several different ways.
There are important differences between how a web container processes a forward request versus how it processes a redirect. The Struts front controller servlet, discussed in Chapter 1, will always perform one or the other for a typical request, so it's important that you understand these differences and the impact that each mechanism will have on your application.
When the sendRedirect() method is invoked, it causes the web container to return to the browser a response indicating that a new URL should be requested. Because the browser issues a completely new request, any objects that are stored as request attributes before the redirect occurs will be lost. This is one of the biggest differences between a forward and redirect. Figure 2-5 illustrates why this occurs.
Figure 2-5: A redirect causes the browser to issue a new request
Because of the extra round trip that occurs, a redirect is slower than a forward. Example 2-1 provides an example servlet that performs a redirect for a JSP page called result.jsp when a request for the servlet is issued.
Example 2-1. A Java servlet that performs a redirect when it receives a request
package com.oreilly.struts.chapter2examples;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;

public class RedirectServlet extends HttpServlet {

  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException,IOException {
    redirect(request, response);
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException,IOException {
    redirect(request, response);
  }

  /**
   * Set a few URL parameters and objects for the request to see what happens
   * to them during a redirect.
   */
  protected void redirect(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException,IOException {

      log("A request arrived for " + req.getServletPath( ));

      req.setAttribute("firstName", "John");
      req.setAttribute("lastName", "Doe");

      String contextPath = req.getContextPath( );
      String redirectStr = contextPath + "/result.jsp?username=foo&password=bar";
      log("redirecting to " + redirectStr);

      // Always call the encodeRedirectURL method when perfoming a redirect
      resp.sendRedirect(resp.encodeRedirectURL(redirectStr));
  }
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Overview of the Struts Framework
It's finally time to introduce the Struts framework. Familiarity with the material from the previous two chapters will allow you to absorb the information here much faster. This chapter provides an overview of the Struts framework. It does not attempt to cover all of its features or go into significant depth; instead, it emphasizes how all the pieces fit into the MVC and Model 2 architecture presented in Chapter 1.
The rest of the book will be spent pulling back the layers and uncovering the details of the framework, expanding on the basic concepts and terminology introduced here. It is important that you have a firm grasp of the fundamentals presented in this chapter—even if you are familiar with the basic concepts of the Struts framework, you should read through this chapter before going on.
This section introduces an online banking application that will be used to familiarize you with Struts. The example presented here is not complete, but it provides an overview of the major components that are present in all Struts applications and shows how those components fit together. A more comprehensive and thorough shopping- cart example will be used throughout the rest of the book.
Most people are familiar with the concept of online banking, so we won't spend too much time explaining the business requirements. In short, the online banking application will allow an end user to log in to the financial institution's web site, view account information, and transfer funds from one account to another (assuming the user has more than one account). The user must present a valid set of credentials to enter the site—in this case, an access number and a personal identification number (PIN).
If the user leaves one or both fields blank, the application will display a formatted message informing the user that both fields are required. If the user enters values for both fields but the authentication fails, the login screen will be redisplayed, along with a formatted error message informing the user that the login has failed. Figure 3-1 shows the online banking login screen after an invalid login attempt has been detected.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
A Banking Account Example
This section introduces an online banking application that will be used to familiarize you with Struts. The example presented here is not complete, but it provides an overview of the major components that are present in all Struts applications and shows how those components fit together. A more comprehensive and thorough shopping- cart example will be used throughout the rest of the book.
Most people are familiar with the concept of online banking, so we won't spend too much time explaining the business requirements. In short, the online banking application will allow an end user to log in to the financial institution's web site, view account information, and transfer funds from one account to another (assuming the user has more than one account). The user must present a valid set of credentials to enter the site—in this case, an access number and a personal identification number (PIN).
If the user leaves one or both fields blank, the application will display a formatted message informing the user that both fields are required. If the user enters values for both fields but the authentication fails, the login screen will be redisplayed, along with a formatted error message informing the user that the login has failed. Figure 3-1 shows the online banking login screen after an invalid login attempt has been detected.
Figure 3-1: Login screen for the online banking application
If the proper credentials are entered for an account, the user is taken to the account information screen. This screen shows all of the accounts that the user has with the financial institution, as well as the current balance for each account.
For this example, we are not going to provide a robust, full-fledged security service and security realm. Handling security in a web application can be complicated, and there's no reason to muddy the waters with it at the moment. For the purposes of this chapter, we'll use a simple Java interface that contains a single
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Looking at the Big Picture
Now that we have described the example application that will be the basis of this chapter's discussion, it's time to start looking at how we can implement it using the Struts framework. Although Chapter 1 discussed the MVC pattern in the order of model, view, and then controller, it doesn't necessarily make sense to follow that order as we explore the Struts components. In fact, it's more logical to cover the components in the order in which the Struts framework uses them to process a request. Thus, we'll discuss the components that make up the controller portion of the framework first.
The Struts framework is made up of approximately 300 Java classes, divided into 8 core packages ("approximately" is an appropriate term because the framework is continuously growing and being shaped). In this chapter, we'll focus on only the top- level packages. Figure 3-4 shows the top-level packages and their dependencies within the framework.
Figure 3-4: The eight top-level packages in the Struts framework
The validator package shown in Figure 3-4 does not represent the entire set of classes and interfaces necessary for the Validator framework. These are only the Struts-specific extensions necessary to use the Validator framework with Struts. There is also a ninth top-level package named config, which consists of a single Java class. We'll ignore this package for now; it's not relevant to the discussion in this chapter.
The framework components are not arranged by what role they play in the MVC pattern—actually, they are arranged a little haphazardly. You might have noticed this by some of the circular dependencies shown in Figure 3-4. This has more to do with how fast the framework has evolved than with poor decisions made by the designers. For example, the action package contains some classes for the controller, some that are used by the view domain, and even a few that probably would have been better off in the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Struts Controller Components
The controller component in an MVC application has several responsibilities, including receiving input from a client, invoking a business operation, and coordinating the view to return to the client. Of course, the controller may perform many other functions, but these are a few of the primary ones.
For an application built using the JSP Model 2 approach, the controller is implemented by a Java servlet. This servlet is the centralized point of control for the web application. The controller servlet maps user actions into business operations and then helps to select the view to return to the client based on the request and other state information. As a reminder, Figure 3-5 shows the figure used in Chapter 1 to illustrate how this works.
Figure 3-5: The Struts framework uses a servlet as a controller
In the Struts framework, however, the controller responsibilities are implemented by several different components, one of which is an instance of the org.apache.struts.action.ActionServlet class.
The ActionServlet extends the javax.servlet.http.HttpServlet class and is responsible for packaging and routing HTTP traffic to the appropriate handler in the framework. The ActionServlet class is not abstract and therefore can be used as a concrete controller by your applications. Prior to Version 1.1 of the Struts framework, the ActionServlet was solely responsible for receiving the request and processing it by calling the appropriate handler. In Version 1.1, a new class, called org.apache.struts.action.RequestProcessor , was introduced to process the request for the controller. The main reason for decoupling the request processing from the ActionServlet is to provide you with the flexibility to subclass the RequestProcessor with your own version and modify how the request is processed.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Struts Model Components
There are several different ways to look at what constitutes a model for Struts. The lines between business and presentation objects can get quite blurry when dealing with web applications—one application's business objects are another's data transfer objects (DTOs).
It's important to keep the business objects separate from the presentation so that the application is not tightly coupled to one type of presentation. It's likely that the look and feel of a web site will change over time. Studies show that the freshness of a web site's appearance helps to attract new customers and keep existing customers coming back. This may not be as true in the business-to-business (B2B) world, but it's definitely true for business-to-consumer (B2C) applications, which make up the majority of the web applications used today.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Struts View Components
The last of the MVC components to discuss are the view components. Arguably, they are the easiest to understand. The view components typically employed in a Struts application are:
  • HTML
  • Data transfer objects
  • Struts ActionForms
  • JavaServer Pages
  • Custom tags
  • Java resource bundles
Struts ActionForm objects are used in the framework to pass client input data back and forth between the user and the business layer. The framework automatically collects the input from the request and passes this data to an Action using a form bean, which then can be passed along to the business layer. To keep the presentation layer decoupled from the business layer, you should not pass the ActionForm itself to the business layer; rather, create the appropriate DTO using the data from the ActionForm. The following steps illustrate how the framework processes an ActionForm for every request:
  1. Check the mapping for the action and see if an ActionForm has been configured.
  2. If an ActionForm is configured for the action, use the name attribute from the action element to look up the form bean configuration information.
  3. Check to see if an instance of the ActionForm already has been created.
  4. If an ActionForm instance is present in the appropriate scope and it's the same type as needed for the new request, reuse it.
  5. Otherwise, create a new instance of the required ActionForm and store it in the appropriate scope (set by the scope attribute for the action element).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Multiple Application Support
Prior to Version 1.1, each Struts application was limited to a single configuration file. The single instance of the file, normally called struts-config.xml, was specified in the web application deployment descriptor. It was the sole provider of the configuration information for the Struts application. The fact that there was only one place to put configuration information made it very difficult for larger projects, because it often became a bottleneck and caused contentions to use and modify this file.
With the advent of multi-application support in Version 1.1, this problem has been alleviated. You now can define multiple configuration files, allowing developers to work better in parallel. Applications modules, as they currently are known, are discussed further in Chapter 4, Chapter 5, Chapter 6, and Chapter 7.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Summary
The Struts framework provides an implementation for the MVC structure, tailored for a web application. The Struts ActionServlet, RequestProcessor, and Action classes provide the controller components; the Action communicates with your application's model components; and the combination of the ActionForm, DTOs, JSP pages, and tag libraries make up the view.
This chapter focused on Struts at a high level and left out many of the details that make the framework even better. Struts, like other valuable software frameworks, allows you to focus on developing the business logic, instead of spending expensive development time on low-level infrastructure functionality such as request dispatching and field-level validation. Hopefully, this peripheral discussion has enticed you to read on and explore the framework details in the rest of the book.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Configuring Struts Applications
The Struts framework uses two separate but somewhat related types of configuration files, which must be configured properly before an application will work correctly. Due to the popularity, flexibility, and self-describing nature of XML, both types of configuration files are based on XML.
The web application deployment descriptor named web.xml is described fully in the Java Servlet specification. This configuration file is necessary for all web applications, not just those built with the Struts framework. However, there is Struts-specific deployment information within it that must be configured when building Struts applications.
Although the Struts framework supports the 2.2 Servlet specification, many servlet containers already have support for Version 2.3. This book includes coverage of the 2.2 and 2.3 specifications.
The second configuration file that we will examine is the Struts configuration file. It is commonly named struts-config.xml, but you can name it just about anything you want. The Struts configuration file makes it possible for you to declaratively configure many of your application's settings. You can think of the Struts configuration file as the rules for the web application.
Throughout the rest of this book, we will construct a shopping-cart type application to use for all of the examples. By the end of the book, we should have a fairly complete application that uses most of the Struts 1.1 features. Figure 4-1 shows the main page of the Storefront example application.
Figure 4-1: The main page of the Storefront application
The Storefront application will demonstrate an e-commerce automotive parts supplier, but you can substitute any items you want as long as you have your own images and data to put into the application. In the end, the Storefront application will be a complete web archive (WAR) file that can be deployed into any compliant web container and used as an example for many different purposes.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Storefront Application
Throughout the rest of this book, we will construct a shopping-cart type application to use for all of the examples. By the end of the book, we should have a fairly complete application that uses most of the Struts 1.1 features. Figure 4-1 shows the main page of the Storefront example application.
Figure 4-1: The main page of the Storefront application
The Storefront application will demonstrate an e-commerce automotive parts supplier, but you can substitute any items you want as long as you have your own images and data to put into the application. In the end, the Storefront application will be a complete web archive (WAR) file that can be deployed into any compliant web container and used as an example for many different purposes.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Is a Web Application?
Applications built using the Struts framework are, at their core, web applications. A web application is a collection of individual components that, once bound together, form a complete application that can be installed and executed by a web container. The components are tied together because they reside in the same web context, which permits them to refer to one another, directly or indirectly. For example, if you have an application running in a web container under a directory called storefront, all of the files in that directory and the directories below it are considered part of the Storefront web application. Any reference to a resource with the "storefront" prefix is routed to this web application. So, if a user types http://www.somehost.com/storefront/index.jsp into his browser's location bar, the JSP page will be served from the root of the Storefront web application.
A web application can be installed and executed in multiple web containers concurrently. For that matter, multiple instances of the same web application can be installed in the same web container. However, because of the manner in which URLs are matched to web applications, each web application must have a unique name within the web container. This means that you can't have two web applications running in the same web container using the same name. The next section takes a closer look at exactly what types of components can reside in a web application.
Not all web applications are created equal. They will not have the same functional and nonfunctional requirements across organizations and departments, or even the same vertical markets. Therefore, not all web applications will contain the same types of resources. In general, however, web applications can consist of one or more of the following types of components:
  • Servlets
  • JSP pages
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Web Application Directory Structure
A web application typically consists of a structured hierarchy of directories. Although the Servlet specification does not require servlet containers to support a hierarchical structure, it recommends that they do so, and most, if not all, comply with this recommendation. The root directory of the hierarchy serves as the document root for the web application. As discussed earlier, requests made using a web application's root context path are served out of the directory for that web application.
Within the web application directory hierarchy, a special directory named WEB-INF must be created. This directory is the repository for meta-information relating to the web application. It is a private directory; no resource within it is accessible to a client. However, the resources in the WEB-INF directory are visible to servlets and Java classes that reside within the web application.
Because the Servlet specification requires that the WEB-INF directory should not be visible to a web client, this is an ideal location for files and other resources that you do not want to expose outside the application. Web application resources such as XML configuration files and other private application resources should be placed within this directory. As you'll see later in this chapter, the Struts configuration file is also normally located here.
The WEB-INF directory is where the deployment descriptor for the web