dcsimg

The Jakarta Struts Framework

The open source Jakarta Struts framework is an immensely popular framework for building Web applications built around the Java 2 Enterprise Edition suite of technologies. Based on the Model-View-Controller pattern, Struts speeds up and simplifies development, letting you focus on business logic rather than infrastructure.

struts_01

In the early days of building Web applications with Java (as if that was so long ago), servlets were the only game in town. While easy to create and conceptually quite simple, servlets were largely monolithic — completely responsible for the end-to-end processing of each client request — and developers found that maintaining a servlet could be quite difficult.

The scenario went like this: for each incoming HttpRequest, the servlet would execute the corresponding business logic, produce the correct output, and return a response (normally in the form of HTML) in an HttpResponse. In other words, the servlet both processed requests and produced output. Servlet code mixed form with function.

That intertwining of — what should be separate — roles inside a single servlet created many nasty entanglements that frustrated developers. Worse, even a simple change to alter the HTML output (say, for a trivial formatting change) required recompilation of the servlet. This was a real annoyance if your application had to be branded or personalized for each customer.

When Java Server Pages (JSP) came along, the new technology addressed many of the problems with servlets. For example, if a JSP was changed, the effects could be seen immediately in the browser — there was no need to manually recompile the JSP — that happened automatically whenever a change was made. However, JSP wasn’t perfect either: developers still got into trouble mixing presentation and business logic in JSP.

That’s a lot of history — and a seemingly convincing argument against servlets and JSP. But ultimately, there’s nothing wrong with servlets and JSP. Used correctly, those technologies can create a wide variety of dynamic Web sites. Trouble is, as you’ve read, using the technologies correctly can be difficult.

And that’s where Struts comes in. Struts, created by the Apache Jakarta project (http://jakarta.apache.org), is an open source framework created specifically to make servlet and JSP-based Web applications easier to build. As the Struts home page says, “The Struts framework provides the invisible underpinnings every professional Web application needs to survive.” If you’re building serious Web applications with Java, Struts should be your foundation.

Models Wanted

The JSP 0.92 Specification presents two approaches as “best practices” for organizing Web applications using servlets and JSP. The two approaches are formally referred to as Model 1 and Model 2.








struts_02
Figure One: JSP Model 1 architecture

The Model 1 architecture uses JSP only. Requests are sent directly to the JSP, where it processes the request and finally generates the HTML to be displayed in the browser. This approach can be seen in Figure One.

The problem with Model 1 is the same as using servlets by themselves: that is, controller, business logic, and presentation logic all reside in the JSP page. This makes it impossible to divide the work among developers. Typically, you want HTML and graphic designers working on HTML layout and Java programmers working on business logic.








struts_04
Figure Two: JSP Model 2 architecture

The second approach, Model 2, adds a servlet into the architecture of Model 1. In Model 2, a servlet acts as a controller, receiving all requests from the client. The servlet hands off the request to a separate business layer for processing. Once processing is complete, the servlet forwards or redirects the request to a JSP, which is solely responsible for generating the next view for the client. There is no business logic within the JSP. The Model 2 architecture is shown in Figure Two.

Introducing a Java servlet into the architecture might seem like a complication in what should otherwise be a very simple and straightforward design. However, there are many benefits to Model 2 that may not be evident at first glance. These benefits can be best understood by discussing an age-old design pattern known as Model-View-Controller, or MVC.

It’s All About Model-View-Controller

The notion of Model-View-Controller was introduced in the Smalltalk-80 user interface in the early ’80s. So what is MVC and what does it have to do with Model 2 or Struts for that matter? Both Model 2 and Struts are realizations of MVC.

MVC is usually referred to as a design pattern, although it also represents a way to construct an application. In general, MVC defines an architecture where the components of a program are divided into three separate categories: the Model, the View, and the Controller. A component that belongs to one of those three categories has unique responsibilities.


  • The components that make up the Model represent the data for the application. MVC doesn’t dictate what type of objects must make up the Model. In Java, they might be standard JavaBeans in a Web application or entity beans in an EJB application. Whatever type of component architecture you’re using, the Model portion of MVC represents the state of the application.

  • The View components are used to render or present the Model’s state information. Presentation is normally done by user interface components like Swing GUIs or JSPs (at least in the case of Java applications).

  • The Controller is one or more components that act as a conductor, orchestrating requests, responses, model changes, and notifications, and keeping everything working together.








struts_03
Figure Three: MVC’s separation of responsibilities

Figure Three illustrates the logical breakdown of MVC within an application. In the traditional use of MVC, like that used in Smalltalk, the Model notifies the View when changes occur to the state of the Model and the View queries the Model for the state information. With Web applications, this is difficult since a browser typically pulls rather than pushes. For example, when the state of an entity bean changes, a browser is generally not aware of the changes until it “pulls” the changes into the browser.

In the original adaptation of MVC, the Controller was also an abstraction of an input device like the keyboard or mouse. Within Web applications, like those built with the Struts framework, the Controller is any central component that receives, directs, and manages user requests. As you’ll see later, one of the key Controller components in a Struts application is a Java servlet. In fact, if you look back at Figure Two, you can overlay the MVC picture onto the Model 2 architecture. The Model is represented by JavaBeans or some other state objects that might be constructed from a datastore. The Views are JSPs, and the primary Controller component is a Java servlet.

Model-View-Controller has several key advantages as an architecture for a Web application (whether or not you use Java). Namely, MVC separates concerns, provides a single point of entry, and supports multiple views on the same Model.


  • Separating the components into those for the Model, the View, and the Controller allows developers to work in parallel without worrying about which components have what responsibilities. HTML and graphic designers to design and create the Web pages — there’s no need for the designers can worry about JSPs. Likewise, you can have Java programmers create the Controller and Model components without worrying about HTML or JavaScript. MVC makes the tasks independent, meaning maintenance, customization, and new features are all easier, to do.

  • Since the Controller receives all requests, there is a single point of entry — a single place where requests are processed and dispatched. Common request processing subsystems like security, logging, and auditing can all be placed in the Controller, once again simplifying maintenance and development.

  • To appreciate the benefits of multiple Views, consider a banking application where a customer can access his or her account in many ways: he can walk into the branch and speak with a teller, can call a service center, or can login to the bank’s Web site. Since each “touch point” is a distinct View of the (sole) Model, no matter how a customer interacts with the bank, the user has the same number of accounts and the same balances — only the user interface differs.

After all of this introduction, let’s jump into Struts.

Introducing Jakarta Struts

Struts was originally created by Craig McClanahan and was donated to the Apache Software Foundation in 2000. Struts provides a thin, but very rich framework for building Java-based Web applications. Chances are that the features and infrastructure provided by Struts are sufficient for most Web applications.

At a high-level, Struts supports the MVC architecture; provides dynamic exception handling capabilities; supports declarative configurations; supports a wide array of technologies to be used for the views (for example, JSP and XSLT); provides for extensions and internationalization; and supports different Model architectures including JavaBeans, JDO, EJB, and others.

Developers who are unfamiliar with Model 2 or MVC might find the learning curve of Struts a little steep. However, if you’re already comfortable with servlets, JSP, and JSP custom tag libraries, you’re more than half way there.

Currently, Struts 1.1 is in late-beta and is very close to a final release (in fact, it may be released by the time you read this). But don’t let the beta status fool you: current nightly builds are good enough for production.

The Struts framework includes several small example applications that can be installed into a container like Tomcat and used as tutorials. Here, we’ll use a more “real-world” example, the beginnings of an online banking application. It’s by no means complete, but should provide a little more realism for the types of applications that are possible with the Struts framework.

Overview of the Struts Architecture

As mentioned earlier, Struts is a framework based on Model 2. Some Struts components belong to the Model, some to the View, and some to the Controller. The Struts framework consists of approximately 280 classes within eight top-level Java packages.

The Struts classes capture user requests, direct the requests to special business logic handlers, and forward the request and any results of the request off to a View component. The framework can also manage user locales, render localized messages, detect invalid input, display error messages, and handle many other tedious tasks (so you don’t have to).

The easiest way to understand the pieces of the Struts framework is by examining them against the MVC architecture. Let’s start with the components that make up the controller section first.

by Chuck Cavaness








struts_05
Figure Four: The high-level request/response scenario in Struts

by Chuck Cavaness

When a request arrives at the Web container, it’s directed to the main Controller servlet. In the Struts framework, ActionServlet acts as the Controller.

The job of the ActionServlet is to receive all incoming requests and direct them to the appropriate handler. Once processing of the request is complete, the ActionServlet forwards the request to a View component (often a JSP) where a response can be returned to the client. In earlier versions of the framework, the ActionServlet fulfilled this responsibility by itself.

Starting with version 1.1, a new class called RequestProcessor assists the ActionServlet. The purpose of this additional Controller class is to allow for more customization of the Controller. The RequestProcessor can be extended and customized based on your application’s needs. The RequestProcessor also determines what handler should process the request. This so-called handler is actually a Struts Action class.

The Action class is a standard Java class with an execute() method. An Action generally implements a single function like login, logout, or retrieving account detail. When the execute() method is invoked by the RequestProcessor, the Action carries out the behavior specific for that function. Figure Four also illustrates a generic request/response scenario for a Struts application.

The RequestProcessor determines which Action class to invoke based on the URL request and an XML configuration file that we’ll discuss momentarily. The job of the Action class is to couple a particular user request to a business method. The business logic isn’t programmed into the Action class, but is invoked by Action calling a service/model layer. It’s actually very bad practice to program any business logic into the Action class because it limits your ability to reuse the business logic across channels.

The Action class provided by the Struts framework is abstract. All application Action classes must extend this abstract class or be a descendant of it. Listing One shows an Action class called LoginAction. This Action could represent the login behavior for almost any application (it’s used here just to provide an illustration of what typically goes on within an Action class). When a login URL request is sent by the browser, the RequestProcessor calls the execute() method of this class.




Listing One: The Action class to login to the bank


public class LoginAction extends Action {
public ActionForward execute( ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {

1 UserView userView = null;

// Get the credentials from the LoginForm
2 String accessNbr=(LoginForm)form).getAccessNumber();
3 String pinNbr = ((LoginForm)form).getPinNumber();
4 IAuthentication service = new SecurityService();

// Attempt to login

5 userView = service.login(accessNbr, pinNbr);
// Invalidate existing session if it exists

6 HttpSession session = request.getSession(false);
7 if(session != null) {
8 session.invalidate();
9 }

// Create a new session for this user
10 session = request.getSession(true);

// Store the UserView into the session and return
11 session.setAttribute(
12 IConstants.USER_VIEW_KEY, userView );
13 return mapping.findForward(IConstants.SUCCESS_KEY );
}
}

There are usually many Action classes for a single application — but there’s only one instance of each Action. That instance handles all requests for that Action. Since all parameters are passed into the execute() method and there are no client-specific instance variables, all client threads can share the same instance. As with servlets, you must be careful to make your Action classes thread-safe by not creating any client-specific instance variables.

There’s no business logic contained within LoginAction, only logic for presentation. On lines 4 and 5, an authentication service is called to verify the user’s credentials. The logic for this authentication is not coded inside the Action class. If it were, it wouldn’t be reusable. Moreover, Action is unaware of how the authentication service works. It could be a relational database, an LDAP implementation, or any other type of service. This lack of knowledge or coupling gives great freedom and flexibility to the application.

The Model

The Struts framework doesn’t provide any special components or framework to handle the Model portion of MVC. At first this might seem shortsighted, but the fact is that’s how it should be. There are already so many component model architectures, including EJB, that there’s no reason for Struts to invent and promote another. Instead, the Struts framework doesn’t limit you in any way, and you are free to use whatever Model layer you need.

Back in Listing One, the authentication service might be implemented as an EJB Session bean, but the Action doesn’t need to know that because the true implementation is hidden behind the service layer.

You might have noticed the UserView object returned from the login() method. Struts works well with standard JavaBeans and they are used quite frequently throughout the framework. JavaBeans can be stored in the request, session, or application scopes, and Struts can use the data to build dynamic views.

Listing Two shows the very simple UserView class that represents the data cached in the HttpSession once a user’s been authenticated.




Listing Two: Struts works well with simple JavaBeans


public class UserView implements java.io.Serializable {
private String id = null;
private String lastName = null;
private String firstName = null;

// A unique collection of permission String objects
private Set permissions = new HashSet();

public boolean containsPermission(String permName) {
return permissions.contains(permName);
}

public String getLastName() {
return lastName;
}

public void setLastName(String name) {
lastName = name;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String name) {
firstName = name;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}

As you can see from Listings One and Two, Struts operates on various types of Model objects. This is a big bonus when you don’t want to tie your application to a specific Model implementation.

The View

In general, MVC doesn’t dictate what technology you use for the View. Java clients can use Swing or perhaps the Standard Widget Toolkit (SWT) from IBM (for more on SWT, see next month’s Linux Magazine feature story on Eclipse and SWT). Because MVC separates concerns, you are free to use different View technologies with the Struts framework.

For example, if you want to use XSLT to transform XML for the client, you can. If your application is required to work with mobile devices, you can easily render Wireless Markup Language (WML). Other technologies like JavaServer Faces are also usable with the Struts framework. Currently, many developers are using JSP to build HTML views that are rendered for the client.

Capturing Form Data

Another interesting feature of Struts is a built-in ability to capture HTML form data, validate it based on a set of rules, and display error messages to the user if problems are detected. One of the framework components that provides these features is the ActionForm.

An ActionForm is essentially a JavaBean. It contains instance variables as well as getters and setters. When a user submits an HTML form, the framework automatically captures the request parameters from the form and creates and populates the ActionForm with the data. ActionForm has a method called validate() that you can override to provide customized validation rules. Assuming that you’ve configured the framework to validate the data (which isn’t mandatory), the framework generates user-readable error messages if validation fails.

Listing Three shows an example LoginForm that might be used with the LoginAction in Listing One.




Listing Three: A sample Struts ActionForm


public class LoginForm extends ActionForm {
private String pinNumber;
private String accessNumber;

public void setAccessNumber(String nbr) {
this.accessNumber = nbr;
}

public String getAccessNumber() {
return this.accessNumber;
}

public String getPinNumber() {
return this.pinNumber;
}

public void setPinNumber(String nbr) {
this.pinNumber = nbr;
}

public ActionErrors validate(ActionMapping mapping,
HttpServletRequest req ) {
ActionErrors errors = new ActionErrors();

// Get message resources for the application
MessageResources resources = (MessageResources)
req.getAttribute(Action.MESSAGES_KEY);

// Check and see if the access number is missing
if(accessNumber == null || accessNumber.length() == 0){
String accessNumberLabel =
resources.getMessage( “label.accessnumber” );
ActionError newError =
new ActionError(“global.error.login.requiredfield”,
accessNumberLabel );
errors.add(ActionErrors.GLOBAL_ERROR, newError);
}

// Check and see if the pin number is missing
if(pinNumber == null || pinNumber.length() == 0){
String pinNumberLabel =
resources.getMessage( “label.pinnumber” );
ActionError newError =
new ActionError(“global.error.login.requiredfield”,
pinNumberLabel );
errors.add(ActionErrors.GLOBAL_ERROR, newError);
}

// Return the ActionErrors, in any.
return errors;
}

}








struts_06
Figure Five: Struts captures and validates form data automatically

If the user fails to enter an access number and a PIN for login, the validate() method generates errors and returns them. The framework directs the user back to a predetermined page, where a JSP tag takes the errors and displays nice messages to the user. You get all of this for free with the framework. All you have to do is provide the specific validation rules that you want for each ActionForm.

Figure Five illustrates the steps that take place for each user request and shows how the framework populates and validates the ActionForm.

Prior to Struts version 1.1, the only way to provide the validation rules were to code them in the ActionForm‘s validate() method. However, using a recently added feature called the Struts Validator, validation rules can be specified declaratively in a separate XML file. The Struts Validator is explained in more detail in the section on new features.

JSP Custom Tags

One of the most time-consuming aspects of building Web applications with JSP is constructing a suitable library of JSP tags. Struts can save you all that time.

Struts provides six tag libraries filled with tags that almost every application requires. The tags are loosely separated into logical groups. Table One lists the six tag libraries and describes the purpose of each one.




Table One: Custom JSP tag libraries included with Struts










Tag Library NamePurpose

BEAN

Contains tags useful in accessing JavaBeans and their properties, as well as defining new beans that are accessible to the remainder of the page via scripting variables and page scope attributes.

HTML

Contains tags used to create Struts input forms, as well as other tags generally useful in the creation of HTML-based user interfaces.

LOGIC

Contains tags that are useful in managing conditional generation of output text, looping over object collections for repetitive generation of output text, and application flow management.

NESTED

Contains tags that extend the base Struts tags to allow them to relate to each other in a nested fashion.

TEMPLATE

Contains tags that are useful in creating dynamic JSP templates for pages that share a common format. These templates are best used when it is likely that a layout shared by several pages in your application will change. The functionality provided by these tags is similar to what can be achieved using standard JSP include directives, but are dynamic rather than static.

TILES

The Tiles tags are used with the Tiles framework, which is a robust framework for assembling presentation pages from component parts. Each part, or tile, can be reused as often as needed throughout your application. This reduces the amount of markup that needs to be maintained and makes it easier to change the look and feel of a website.

The Validator framework also includes several custom tags for assisting in server-side and client-side presentation validation. By relying on Strut’s custom tags, you can avoid or at least limit the amount of Java code that’s necessary within the JSP.

Less Java means less maintenance and better reuse since the tags only have to be written once. You can also avoid the costly copy-and-paste errors that occur when using Java within JSPs.

Struts Configuration Files

Like many other frameworks and applications built with Java, XML plays a major role within the Struts framework. The framework uses XML for all of its configuration files.

Although the number of configuration files needed depends on which features you use, there is always at least two XML configuration files and one Java properties file for each and every Struts application.

The first configuration file is not specific to Struts. All web applications require a Web Application Deployment Descriptor (WADD). This file, which is mandated and described in detail within the servlet specification, allows you to configure each deployment of the application. The file must be named web.xml and must reside within the WEB-INF directory for the Web application.

An example deployment descriptor for the banking application is shown in Listing Four.




Listing Four: The Web Application Deployment Descriptor for the banking application

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE web-app
PUBLIC “-//Sun Microsystems,
Inc.//DTD Web Application 2.3//EN”

http://java.sun.com/dtd/web-app_2_3.dtd“>

1 <web-app>

2 <servlet>

3 <servlet-name>banking</servlet-name>

4 <servlet-class>

5 org.apache.struts.action.ActionServlet

6 </servlet-class>

7 <load-on-startup>1</load-on-startup>

8 </servlet>

9 <servlet-mapping>

10 <servlet-name>banking</servlet-name>

11 <url-pattern>/action/*</url-pattern>

12 </servlet-mapping>

13 <welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>

16 <taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>

20 <taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>

24 <taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
}

There are three sections in Listing Four that are worth pointing out.


  • The first important section begins on line 2 and continues to line 8. The element <servlet> sets the name of the Web application and specifies the Struts ActionServlet that acts as the primary Controller. (You are free to extend the ActionServlet if you need to customize it for any reason. If you do, you’d place the full path of your ActionServlet class on line 5, in place of the default one that ships with Struts.)

  • The second area of interest is between lines 9 and 12. The <servlet-mapping> element describes which URL requests are going to be sent to the banking application. Line 11 specifies that any request that has a pattern of /banking/action/ will be handled by the banking application. The asterisk indicates that the request can have anything following the word action/. This type of mapping is known as path mapping. (Struts also supports extension mapping, which you might be familiar with if you’ve ever seen something like *.do. When using extension mapping, URL requests must have “.do” at the end of the request. The decision to use path mapping or extension mapping mainly comes down to preference.)

  • The final section of interest is the inclusion of the tag library descriptor files on lines 16, 20, and 24. These lines tell the Web container which JSP custom tag libraries are used by the Web application. The banking application is only using the HTML, Bean, and Logic tag libraries.

The second, and by far the most important configuration file is the Struts configuration file, which is commonly named struts-config.xml. This file allows you to declaratively configure just about everything there is to configure for a Struts application. Within the file you can specify Action classes and their associated URLs; ActionForm classes used to capture HTML form data; global exception handling; message resource bundles; whether the application uses the locale or not; log file settings; and many more.

There’s actually too many configuration options to talk about or show in this article. The best thing to do is read the configuration file section of the Struts User’s Guide or better yet, pick up one of five recent books published on Struts. Chapter 4 of the new O’Reilly book spends an entire chapter on these configuration files.

When the Web container is started, the ActionServlet loads the Struts configuration file and initializes all of the necessary components. Any changes to the configuration file are not picked up until the next restart of the application.

The final configuration file to mention is the resource bundle for the application. The resource bundle is a text file that follows the format and rules of the Java Properties class. The file contains key/value pairs that can be used within the application, which helps externalize messages and make the application easier to port to other languages. Listing Five shows a portion of the resource bundle for the banking application.




Listing Five: The Banking resource bundle


# Labels
label.accessnumber=Access Number
label.pinnumber=Pin Number
label.accounts=Accounts

# Links
link.customeragreement=Customer Agreement

# Page Titles
title.login=Struts Online Banking – Account Login
title.accountinfo=Struts Online Banking – Account Information

# Button Labels
label.button.login=Login

# Error messages
global.error.invalidlogin=<li>Invalid Access Number and/or Pin</li>

global.error.login.requiredfield=<li>The {0} is required for login</li>

# Images
image.logo=images/logo.gif
image.logo.alt=Struts Online Banking

Within the JSPs, the values on the right-hand side of the equal (=) sign can be written out by using a Struts tag and the name on the left hand side. For example, Listing Six shows a snippet from the login.jsp page. Using the message tag from the bean tag library, you can write out the value from the resource bundle that contains the key title.login.




Listing Six: Part of login.jsp that uses the bean:message JSP tag


<head>
<html:base/>
<title><bean:message key=”title.login”/></title>
</head>

The Message tag performs a lookup from the bundle using the key title.login and finds the value Struts Online Banking – Account Login. The JSP insert this value into the HTML <title> tag.

The values from the resource bundle can also be accessed by the Action classes and/or other components, not just the JSP pages. This is a very powerful feature.

An Example Struts Application

By now, you’re probably more than ready to get your hands dirty with the framework. The rest of this article will be devoted to taking you through the steps of creating a simple Struts application, installing it into a container, and running it.

Under normal circumstances, the first thing that you’d need to do is download the Struts framework. Fortunately, the file banking.war (which you can download from http://www.linux-mag.com/downloads/2003-03/struts/banking.war) contains all of the code you need, including the Struts framework. Source code and the latest release of Struts can be found at http://jakarta.apache.org/struts.

The Struts site also has a set of instructions for installing the framework into various containers. For this article and our banking example, let’s use Tomcat 4.1.18. If you don’t already have Tomcat installed, you can download Tomcat from http://jakarta.apache.org/tomcat. Tomcat will need to be installed before the banking or any other Struts example can be run.

(Many other popular containers also support Struts, including BEA’s WebLogic, IBM’s WebSphere, and many more. You can find a complete list of supported containers on the Struts site.)

Our banking application has the following features: authenticate a user login; show a list of accounts for the user; show details for each account; and perform a logout. Obviously, there’s more to an online banking application than what’s listed here, but these features are just enough to give you a true Struts experience.

The easiest way to run the application is to drop the banking.war file into Tomcat’s webapps directory. Tomcat will automatically explode the war file and make it available to clients. You should run the example just to get a feel for the rest of the discussion. The source code for the various Struts components and JSPs are also included for review at your leisure. There’s also an Ant script so you can build the banking application from scratch if you’d like.

Configuring the Banking Application

For convenience, the banking application is already partially created for you. This makes it easier for you to explore the framework right now without having to write code to get it working. Later on, you might want to see if you can extend the existing features by finishing the account transfer feature.

If you were starting from scratch, you’d have to develop the Action classes, ActionForms, the business logic, data layer code, utility classes, and JSPs. Normally, this work is divided among the developers on a project team. Depending on the team size, managing the Struts configuration file can be a daunting task. This is because it quickly becomes a bottleneck, as the file needs to be updated often during development.

Rather than using your favorite text editor to modify the Struts configuration file, there are several free and several commercial GUI tools that can help. One of the most popular tools is a free tool called Struts Console. You can find more information on the Struts Console at http://www.jamesholmes.com/struts/console.

Running the Banking Application

Once you have Tomcat (or another supported container of your choice) and the banking.war file installed, startup the container and let it completely come up. Open up a browser and type http://localhost:8080/banking. The number 8080 is the default port that Tomcat listens on. (If you’re using a different container, you should specify its default port.)








struts_07
Figure SIX: The sample banking application login screen

Once you type the URL and hit Enter, you should see a screen similar to that shown in Figure Six. Run through the application. There’s virtually no difference between a Struts application and one written with something like Active Server Pages (ASP).

New 1.1 Features

An article on Struts would be incomplete if it omitted the great features in 1.1. After all, the features in 1.1 are truly what makes Struts “ready for prime time.” Here are the most prominent additions:


  • The Validator framework allows Struts application (and non-Struts applications alike) to declaratively configure a set of validation rules for an application. The rules are configured outside of the application source code and the rules can be modified without recompiling the application. The Validator framework is also very extensible: it’s very easy to add new rules or change existing ones. Although the Validator ships with Struts, it’s also a separate sub-project under the Jakarta Commons project. You can find more information on the Validator at http://jakarta.apache.org/commons/validator.

  • The Tiles framework is a set of Java classes and JSP tags that allow you to assemble Web pages using the concept of templates. Tiles allows complicated Web pages to be created and reused across an application or across applications. The Tiles framework is now part of the Struts framework, but much more information can be found at the creator’s site, http://www.lifl.fr/~dumoulin/tiles.

  • Prior to version 1.1, all rules and configuration settings for a Struts application existed in a single Struts configuration file. Although this worked, there were issues with contention among larger development projects. A new feature called Application Modules allows a single Struts application to be split into multiple configuration files. It also allows an application to be organized along functional lines, which better reflects and supports the way applications are developed and sold.

  • Handling exceptions programmatically means that your application code contains try/catch blocks (typically within Action classes) to catch and handle exceptions thrown throughout the application. Declarative exception handling serves the same purpose, but you don’t have to put try/catch blocks in your application. Instead, you use the Struts configuration file to specify which Action classes throw which system or application exceptions. Once that’s done, the framework catches exceptions and executes the behavior you prescribe for it. By default, the behavior is to generate a user message and forward to a specific view. Within the view you can notify the client, perhaps with a message from the resource bundle so the user message is friendly. The really nice part is that you can customize the behavior to do just about anything you like. This might include logging the exception and re-throwing the exception as something else. The framework even allows you to mix programmatic and declarative exception handling if the need arises.

  • Earlier in this article, you saw how Struts ActionForm captures the HTML form data. An ActionForm can also be validated and any validation can be communicated to the user. One of the downsides of using ActionForm has been the need to create extra JavaBean objects that capture data only for the purpose of discarding them after validation is finished. The data from the ActionForm is typically transferred to the Model layer so that the Model layer is not coupled to the Struts framework (remember that we want to be able reuse the model with multiple presentation technologies). For any non-trivial application, the number of ActionForm classes can climb quite high. This adds a sizable amount of development and maintenance time keeping these ActionForm classes up to date. With Dynamic Forms (or DynaForms, as they are sometimes called), it’s no longer necessary to create ActionForm classes because the framework can do it for you at runtime. In Struts 1.1, you can now configure an ActionForm solely within the configuration file. The XML snippet in Listing Seven shows how to configure a dynamic ActionForm that serves the same purpose as the one in Listing Three. At runtime, the Struts framework creates an ActionForm called “loginForm” that you can use exactly like the one in Listing Three, except that you don’t have to actually code the class.




Listing Seven: Configuring dynamic forms


<form-bean
name=”loginForm”
type=”org.apache.struts.validator.DynaValidatorForm”>
<form-property
name=”accessNumber”
type=”java.lang.String”/>

<form-property
name=”pin”
type=”java.lang.String”/>
</form-bean>

This list of new features is not exhaustive. There are many other features that increase the value of the framework, but are not as monumental. For a complete list of new features, see the Struts Roadmap page at http://jakarta.apache.org/struts/ status.html.

Where to go from Here?

Struts is a very rich framework for building Web applications with J2EE technologies. This overview was just for starters — there’s absolutely no substitute for any of the five Struts books that were recently released.

You can also find a large amount of information on the Struts resources page, including links to the books, many articles, and tons of other helpful tidbits. The Struts resources page can be found at http://jakarta.apache.org/struts/ resources.

Another great source of information is the Struts mailing lists. Traffic is quite high, but you can simply read the list if you don’t want to subscribe.

Check out the Apache EyeBrowse tool at http://nagoya. apache.org/eyebrowse. EyeBrowse is a web-based tool that lets you view all of the public Apache mailing lists. EyeBrowse is quite handy because you don’t have to subscribe to a list to view the messages.



Chuck Cavaness is a Senior Technologist at S1 Corporation (www.s1.com). His expertise spans server-side Java, distributed object computing, and application servers. His latest book, “Programming Jakarta Struts,” is published by O’Reilly. You can download the code shown in this story from http://www.linux-mag.com/downloads/2003-03/struts.

Comments are closed.