ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


JSP and Servlets

Introduction to Jakarta Struts Framework

09/11/2001

Web application development was once simple: there was an HTML page and a browser. That was it. No dynamic data, no business applications, no headaches. But that simplicity lasted for only a short time. Today we are faced with complicated Web and business application development using a plethora of technologies.

This article focuses on one aspect of that development process: how to use the Struts framework to assist in front end integration. Struts is an open source framework developed for encouraging an application architecture based on the Model-View-Controller (MVC) design paradigm, useful in building Web applications with Java servlet and Java Server Pages (JSP) technology.

This article assumes a working knowledge of JSP, servlets, custom tag libraries, and XML. Refer to some of my previous columns on JSP customer tag library development if you need to brush up on the basics. This column is Part One in a two-part series on using the Struts framework.

In The Beginning

Struts is a Model-View-Controller (MVC) framework compatible with Sun's J2EE platform and primarily based on servlet and JSP technology. The Struts framework has been around for about a year now and was originally conceived by Craig McClanahan. Struts is now part of the Jakarta project (which is part of ASF, the Apache Software Foundation). The official home for Struts is at http://jakarta.apache.org/struts. The framework has gained considerable attention over the course of the last year because of its ease of use and ability to fit today's developers' needs in building applications and building them fast. Struts combines Java servlets, Java Server Pages (JSP), custom tags, and message resources into a unified framework and saves the developer the time of coding an entire MVC model, a considerable task indeed.

The Struts package, even though it is a revision 1.0, has complete documentation. This includes a user's guide as well as developer's guides. If you are a new JSP programmer or aren't familiar with using the MVC design pattern, this might be a chunk to chew off in the beginning, but you will come up to speed quickly.

One thing important to note is that even though this is a 1.0 product, it is extremely stable. I have been using the Struts framework since the 0.9 version (and have recently updated to the 1.0 release) on a large-scale client project, and have not experienced any problems with it. In fact, it has saved our team a considerable amount of engineering time for the complex screen interactions of this particular project. Kudos to the contributing developers who work on the Struts project.

Comment on this articleIn general, what has been your experience with Apache's Jakarta projects?
Post your comments

Also in JSP and Servlets:

Learning the New Jakarta Struts 1.1, Part 2

Learning the New Jakarta Struts 1.1, Part 1

JSP Standard Tag Libraries, Part 2

Also importantly, if you are just starting out with the framework, the Struts' mailing list has a fair amount of activity, and can be found along with the other open source Jakarta projects at http://jakarta.apache.org/site/mail.html.

Bring on the Framework

The framework itself can be broken down into four primary areas, three of which correspond nicely to the MVC pattern:

Let's examine the various parts of the framework and get a feel for the interaction of objects in the system.

Configuration

Before being able to use Struts, you must set up your JSP container so that it knows to map all appropriate requests with a certain file extension to the Struts action servlet. This is done in the web.xml file that is read when the JSP container starts. While it's possible to define multiple controllers in the web.xml file, one for each application should suffice. A web.xml file that defines a simple configuration is below; the comments explain the content. We'll talk about the details of the struts-config.xml file when we get to the Action class.

<web-app>
  <servlet>
<!--
Declare the OreillyAction servlet to be of type ActionServlet from the framework. Include the configuration file as defined in the config param. Set the debug level to 2 with a detail of 2 when loading the servlet. Create 2 instances.
-->

    <servlet-name>OreillyActionServlet</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
<!--   
  All incoming requests that end in .action, send to the OreillyActionServlet.
-->
<servlet-mapping>
    <servlet-name> OreillyActionServlet </servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
<!--   
  Send initial requests to the login page for this application
-->  
<welcome-file-list><welcome-file>login.jsp</welcome-file></welcome-file-list>
<!--   
  Make all of the necessary related Struts JSP custom tag libraries
available and define where to find them.
-->
  <taglib>
    <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
    <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
  </taglib>
  <taglib>
    <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
    <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
  </taglib>
  <taglib>
    <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
    <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
  </taglib>

</web-app>

The Controller

The controller is really the traffic cop of the framework and determines when things happen. The controller servlet is responsible for packaging and routing HTTP request to the appropriate object in the framework. This is either a JSP page or an Action class.

The controller is in the web.xml file as an instance of org.apache.struts.action.ActionServlet. In our sample above, this is the OreillyActionServlet. When the control is initialized, it reads a configuration file (struts-config.xml) that specifies action mappings for the application, as well as a slew of other things that we'll discuss later. The controller then uses these action mappings to determine where to send the HTTP request. The application action then takes over and performs whatever business logic is necessary. An important aspect to note is that Action objects have access to the servlet's methods. This is a powerful feature, because when the Action object forwards control to another object, one or more shared objects can be forwarded as well by adding them to one of the standard collections shared by Java servlets.

The Model

The model is an object that takes the request from the user and stores the results for the duration of the process. Usually a JavaBean passes along the information in the process. Model objects are typically application specific since they are basically the business logic of the application. Struts provide the ActionForm and Action classes, which extends to model objects creation. It is in these model objects where form validation, or any type of preprocessing of request data that is necessary, usually takes place. It's possible to have a one-to-one correlation between model objects and request pages, but it's not necessarily required. It's also quite possible to reuse a model object for multiple page requests. If there is no action necessary for a model object, the controller can send the request directly to the view object, as specified in the struts-config.xml.

Struts-config.xml

The struts-config.xml file is really the glue of the entire framework. While web.xml defines where a request should go upon arriving, struts-config.xml determines exactly what will happen to it. It's the Vito Corleone of the Struts framework; nothing happens without its okay and knowledge. This is where the mappings of actions are defined. As with the growing number of XML configuration files, the advantage of using one is in keeping a system modular and easy to maintain. It prevents the hard coding of objects to be called within a component. Changes can be made on the fly by changing the configuration files without having to re-deploy applications.

The controller uses the struts-config.xml file to determine which object to call for a given action request. The file is read on startup and the relationships are stored in memory for optimal performance. A bare minimal struts-config.xml is shown below. This just defines a login action so that when a login request is received, it will be forwarded to an instance of the action object com.oreilly.ui.authentication.actions.LoginAction. The return of that class will determine which page to forward to from there. This sample also illustrates the ability to forward to other model objects; otherwise, it returns back to a view object, in this case the login.jsp file.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
  "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">

<struts-config>
  <!-- ========== Action Mapping Definitions=================== -->
  <action-mappings>
    <!-- Attributes of the <action> element -->
<!-
type - Fully qualified Java class name of the Action
    implementation class used by this mapping.
name - The name of the form bean defined in the config
    file that this action will use
path - The request URI path that is matched to select this
    mapping unknown - Set to true if this action should be
    configured as the default for this application to
    handle all requests not handled by another action.
    Only one action can be defined as a default within
    a single application.
validate - Set to true if the validate() method of the
    action associated with this mapping should be called.
-->
    <!-- ~~~~~~~~~~~~~~~~~~~~~ -->
    <!-- O'Reilly Main Actions    -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~ -->
    <action path="/Login"
           type="com.oreilly.ui.authentication.actions.LoginAction">
      <forward name="success" path="/DisplayMainPage.action"/>
      <forward name="failure" path="/login.jsp"/>
    </action>
  </action-mappings>
</struts-config>

The View

The view object is often a JSP page. The Struts framework doesn't actually provide the JSP, but it does provide a number of tag libraries that easily allow JSP integration into the Struts framework. The interaction of Struts with JSP allows for storing data of an input form in a form bean; that is the ActionForm we mentioned earlier. The ActionForm is, then, used by the Action class for doing field validation. If errors are found during validation, there is a shared mechanism available in the framework for raising and displaying error messages.

The Struts framework includes a number of custom tag libraries, which are used in a variety of ways. While the use of these libraries is not required to use the framework, chances are that you will want to explore them. These libraries include:

Additionally, the custom tags in the Struts framework use the internationalization features built into the Java platform by using resource files. To provide messages for another language, simply add another resource file.

Strutting Your Stuff

The Struts framework, while relatively new, is definitely holding its own with developers. It's found in a number of applications, and can assist you with new development or existing JSP projects you might be working on.

For example, in a large database application such as the one I am working on for a client, the business-logic beans are implemented as EJBs. A JSP is displayed in the browser. Depending on the form that is being displayed, a specific action takes place, as defined in the struts-config.xml file. The appropriate action class receives the request, does some validation on the form object, and calls the execute method of the appropriate EJB service bean. The results from the EJB are returned in XML that is then parsed. The content is stored in a form bean and then displayed by a JSP.

Related Reading

Java Servlet Programming, 2nd EditionJava Servlet Programming, 2nd Edition
By Jason Hunter with William Crawford
Table of Contents
Index
Sample Chapter
Full Description

The entire control of the flow is done by the struts-config.xml file, depending on return values from the various action classes. This is all centrally located and easy to adjust. Neither the action's servlet nor the JSP need to know (and in proper n-tier development, shouldn't have to care) where the result set that is being displayed comes from.

The only drawback that I've found with the framework from my current project is this: since it is a large-scale project, there are many screens and many request types. It seems that there are many Action classes, since we basically need only one per request type. I think that this could be avoided by doing some careful planning upfront, but for new product development it isn't always possible to identify the common requests. That information gets acquired over time as the application takes shape and new business requirements are defined. Of course, there weren't many Struts samples to use six months ago, either. That one issue aside, Struts has helped save time in coding an entire MVC model, and has definitely been stable enough to use and benefit from in production products.

In Part Two of this series, we will walk through building a simple Struts application and tie all of the pieces together in a coding sample.

Sue Spielman is an associate editor for ONJava.com, covering JSP and Servlets technologies. She is also President and Senior Consulting Engineer for Switchback Software LLC.


Read more JSP and Servlets columns.

Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.