You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@locus.apache.org on 2000/06/03 00:26:26 UTC

cvs commit: jakarta-struts/web/documentation users_guide.html index.jsp

craigmcc    00/06/02 15:26:26

  Modified:    .        build.xml
               src/share/org/apache/struts/action ActionServlet.java
               web/documentation index.jsp
  Added:       web/documentation users_guide.html
  Log:
  Add a first draft of the user's guide for Struts.
  
  Modify the build.xml file to include generated Javadoc for the Struts
  packages in the "struts-documentation.war" file.
  
  Revision  Changes    Path
  1.3       +16 -1     jakarta-struts/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/build.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- build.xml	2000/06/01 00:05:54	1.2
  +++ build.xml	2000/06/02 22:26:25	1.3
  @@ -82,6 +82,21 @@
                dest="${build.home}/example/WEB-INF/${app.name}.tld"/>
     </target>
   
  +  <!-- BUILD:  Create Javadoc documentation -->
  +  <target name="compile.javadoc">
  +    <deltree  dir="${build.home}/documentation/api"/>
  +    <mkdir    dir="${build.home}/documentation/api"/>
  +    <javadoc sourcepath="src/share"
  +                destdir="${build.home}/documentation/api"
  +           packagenames="org.apache.struts.*"
  +	         author="true"
  +                private="true"
  +                version="true"
  +            windowtitle="Jakarta Struts API Documentation"
  +               doctitle="&lt;h1&gt;Jakarta Struts Package&lt;/h1&gt;"
  +                 bottom="Copyright &#169; 2000 - Apache Software Foundation"/>
  +  </target>
  +
     <!-- DIST:  Construct library distributables -->
     <target name="dist.library" depends="prepare.dist,compile.library">
       <copyfile src="${build.home}/library/${app.name}.tld"
  @@ -92,7 +107,7 @@
   
     <!-- DIST:  Construct documentation distributables -->
     <target name="dist.documentation"
  -       depends="dist.library,compile.documentation">
  +       depends="dist.library,compile.documentation,compile.javadoc">
       <jar  jarfile="${dist.home}/lib/${app.name}-documentation.war"
             basedir="${build.home}/documentation"/>
     </target>
  
  
  
  1.2       +4 -4      jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java
  
  Index: ActionServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ActionServlet.java	2000/05/31 22:28:11	1.1
  +++ ActionServlet.java	2000/06/02 22:26:25	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.1 2000/05/31 22:28:11 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/05/31 22:28:11 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.2 2000/06/02 22:26:25 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/06/02 22:26:25 $
    *
    * ====================================================================
    *
  @@ -140,7 +140,7 @@
    * <p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2000/05/31 22:28:11 $
  + * @version $Revision: 1.2 $ $Date: 2000/06/02 22:26:25 $
    */
   
   public class ActionServlet
  @@ -228,7 +228,7 @@
        *     containing our configuration information.  [/WEB-INF/action.xml]
        * <li><strong>debug</strong> - The debugging detail level for this
        *     servlet, which controls how much information is logged.  [0]
  -     * <li><strong>mapping</string> - The Java class name of the ActionMapping
  +     * <li><strong>mapping</strong> - The Java class name of the ActionMapping
        *     implementation to use [org.apache.struts.action.ActionMappingBase]
        * </ul>
        *
  
  
  
  1.3       +2 -2      jakarta-struts/web/documentation/index.jsp
  
  Index: index.jsp
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/web/documentation/index.jsp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index.jsp	2000/06/01 21:06:27	1.2
  +++ index.jsp	2000/06/02 22:26:26	1.3
  @@ -4,11 +4,11 @@
   </head>
   <body bgcolor="white">
   
  -FIXME - Write the documentation and include it here!<br><br>
  -
   The following documentation is available:
   <ul>
   <li><a href="tags.html">Custom Tag Library Reference</a>
  +<li><a href="users_guide.html">Struts User's Guide</a>
  +<li><a href="api/index.html">Struts API Documentation</a>
   </ul>
   
   </body>
  
  
  
  1.1                  jakarta-struts/web/documentation/users_guide.html
  
  Index: users_guide.html
  ===================================================================
  <html>
  <head>
  <title>Struts User's Guide</title>
  </head>
  <body bgcolor="white">
  
  <div align="center">
  <h1>User's Guide:  Application Design Using Struts</h2>
  </div>
  
  
  
  <h2>1. Introduction</h2>
  
  <h3>1.1 The Model-View-Controller (MVC) Design Pattern</h3>
  
  <h3>1.2 Mapping MVC Concepts to Struts Components</h3>
  
  <h4>1.2.1 The Model:  JavaBeans and Business Logic Classes</h4>
  
  <h4>1.2.2 The View:  JSP Pages and Presentation Components</h4>
  
  <h4>1.2.3 The Controller:  ActionServlet and ActionMapping</h4>
  
  <h3>1.3 Designing For The Future</h3>
  
  
  
  <h2>2. Defining Application Requirements</h2>
  
  <h3>2.1 User Interface Requirements</h3>
  
  <h3>2.2 Functional Processing Requirements</h3>
  
  <h3>2.3 Applications as Conversations</h3>
  
  
  
  <h2>3. Building the View Components</h2>
  
  <h3>3.1 Overview</h3>
  
  <p>Once you have defined the application requirements, work on implementing
  these requirements can begin.  In larger projects, many of these efforts
  can proceed in parallel, because the mutual interdependencies are minimized
  by the use of the MVC design pattern.</p>
  
  <p>This chapter focuses on the task of building the <i>View</i> components
  of the architecture, which will primarily be created using JavaServer Pages
  (JSP) technology.  In particular, the support Struts provides for building
  internationalized applications, and interacting with input forms.  Several
  other topics related to the View components are briefly discussed.</p>
  
  <h3>3.2 Internationalized Messages</h3>
  
  <h4>3.2.1 Background Information</h4>
  
  <p>A few years ago, application developers could count on having to support
  only residents of their own country, who are used to only one (or sometimes
  two) languages, and one way to represent numeric quantities like dates,
  numbers, and monetary values.  However, the explosion of application
  development based on web technologies, as well as the deployment of such
  applications on the Internet and other broadly accessible networks, have
  rendered national boundaries invisible in many cases.  This has translated
  (if you will pardon the pun) into a need for applications to support
  <i>internationalization</i> (often called "i18n" because 18 is the number of
  letters in between the "i" and the "n") and <i>localization</i>.</p>
  
  <p>Struts builds upon the Java platform to provide assistance
  for building internationalized and localized applications.  The key concepts
  of importance are:</p>
  <ul>
  <li><b>Locale</b> - The fundamental Java class that supports
      internationalization is <code>java.util.Locale</code>.  Each
      <code>Locale</code> represents a particular choice of country and
      language (plus an optional language variant), and also a set of
      formatting assumptions for things like numbers and dates.</li>
  <li><b>ResourceBundle</b> - The <code>java.util.ResourceBundle</code> class
      provides the fundmental tools for supporting messages in multiple
      languages.  See the Javadocs for the <code>ResourceBundle</code> class,
      and the information on Internationalization in the documentation bundle
      for your JDK release, for more information.</li>
  <li><b>PropertyResourceBundle</b> - One of the standard implementations of
      <code>ResourceBundle</code> allows you to define resources using the
      same "name=value" syntax used to initialize properties files.  This is
      very convenient for preparing resource bundles with messages that are
      used in a web application, because these messages are generally text
      oriented.</li>
  <li><b>MessageFormat</b> - The <code>java.text.MessageFormat</code> class
      allows you to replace portions of a message string (in this case,
      one retrieved from a resource bundle) with arguments specified at
      run time.  This is useful in cases where you are creating a sentence,
      but the words would appear in a different order in different languages.
      The placeholder string <code>{0}</code> in the message is replaced by
      the first runtime argument, <code>{1}</code> is replaced by the second
      argument, and so on.
  <li><b>MessageResources</b> - The Struts class
      <code>org.apache.struts.util.MessageResources</code> lets you treat
      a set of resource bundles like a database, and allows you to request
      a particular message string for a particular Locale (normally one
      associated with the current user) instead of for the default Locale
      the server itself is running in.
  </ul>
  
  <h4>3.2.2 Development Tasks Required</h4>
  
  <p>For an internationalized application, follow the steps described in
  the Internationalization document in the JDK documentation bundle for your
  platform to create a properties file containing the messages for each
  language.  An example will illustrate this further.</p>
  
  <p>Assume that your source code is created in package
  <code>com.mycompany.mypackage</code>, so it is stored in a directory
  (relative to your source directory) named
  <code>com/mycompany/mypackage</code>.  To create a resource bundle called
  <code>com.mycompany.mypackage.MyResources</code>, you would create the
  following files in the <code>com/mycompany/mypackage</code> directory:</p>
  <ul>
  <li><b>MyResources.properties</b> - Contains the messages in the default
      language for your server.  If your default language is English, you
      might have an entry like this:
      <pre>
  	prompt.hello=Hello
      </pre>
  <li><b>MyResources_xx.properties</b> - Contains the same messages in the
      language whose ISO language code is "xx" (See the ResourceBundle
      Javadoc page for a link to the current list).  For a French version
      of the message shown above, you would have this entry:
      <pre>
  	prompt.hello=Bonjour
      </pre>
      You can have resource bundle files for as many languages as you need.
  </ul>
  
  <p>When you configue the controller servlet in the web application
  deployment descriptor, one of the things you will need to define in
  an initialization parameter is the base name of the resource bundle
  for the application.  In the case described above, it would be
  <code>com.mycompany.mypackage.MyResources</code>.</p>
  
  
  <h3>3.3 Forms and FormBean Interactions</h3>
  
  <h4>3.3.1 Background Information</h4>
  
  <p>At one time or another, most web developers have built forms using
  the standard capabilities of HTML, such as the <code>&lt;input&gt;</code>
  tag.  Users have come to expect interactive applications to have certain
  behaviors, and one of these expectations relates to error handling -- if
  the user makes an error, the application should allow them to fix just what
  needs to be changed -- without having to re-enter any of the rest of the
  information on the current page or form.</p>
  
  <p>Fulfilling this expectation is tedious and cumbersome when coding with
  standard HTML and JSP pages.  For example, an input element for a
  <code>username</code> field might look like this (in JSP)</p>
  <pre>
  	&lt;input type="text" name="username"
  	 value="<%= loginBean.getUsername() %>">
  </pre>
  which is difficult to type correctly, confuses HTML developers who are
  not knowledgeable about programming concepts, and can cause problems with
  HTML editors.  Instead, Struts provides a comprehensive facility for
  building forms, based on the Custom Tag Library facility of JSP 1.1.
  The case above would be rendered like this using Struts:
  <pre>
  	&lt;struts:text name="username"/&gt;
  </pre>
  with no need to explicitly refer to the JavaBean from which the initial
  value is retrieved.  That is handled automatically by the framework.</p>
  
  <h4>3.3.2 Building Forms With Struts</h4>
  
  <p>A more complete example of a login form will illustrate how Struts
  makes dealing with forms much less painful than using straight HTML
  and standard JSP facilities.  Consider the following page (from the
  example application included with Struts) named <code>logon.jsp</code>:</p>
  <pre>
    &lt;%@ page language="java" %&gt;
    &lt;%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %&gt;
  
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;&lt;struts:message key="logon.title"/&gt;&lt;/title&gt;
    &lt;body bgcolor="white"&gt;
  
    &lt;struts:errors/&gt;
  
    &lt;struts:form action="logon.do" name="logonForm"
     type="org.apache.struts.example.LogonForm"/&gt;
    &lt;table border="0" width="100%"&gt;
      &lt;tr&gt;
        &lt;th align="right"&gt;
          &lt;struts:message key="prompt.username"/&gt;
        &lt;/th&gt;
        &lt;td align="left"&gt;
          &lt;struts:text name="username" size="16"/&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;th align="right"&gt;
          &lt;struts:message key="prompt.password"/&gt;
        &lt;/th&gt;
        &lt;td align="left"&gt;
          &lt;struts:password name="password" size="16"/&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td align="right"&gt;
          &lt;struts:submit&gt;
            &lt;struts:message key="button.submit"/&gt;
          &lt;/struts:submit&gt;
        &lt;/td&gt;
        &lt;td align="right"&gt;
          &lt;struts:reset&gt;
            &lt;struts:message key="button.reset"/&gt;
          &lt;/struts:reset&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
    &lt;/struts:form&gt;
  
    &lt;/body&gt;
    &lt;/html&gt;
  </pre>
  
  <p>The following items illustrate the key features of form handling in Struts,
  based on this example:</p>
  <ul>
  <li>The <code>taglib</code> directive tells the JSP page compiler where to
      find the <i>tag library descriptor</i> for the Struts tag library.  In
      this case, we are using <code>struts</code> as the prefix that identifies
      tags from this library, but any desired prefix can be used.</li>
  <li>This page uses several occurrences of the
      <a href="tags.html#message">message</a> tag to look up internationalized
      message strings from a <code>MessageResources</code> object containing
      all the resources for this application.  For this page to work, the
      following message keys must be defined in these resources:
      <ul>
      <li><b>logon.title</b> - Title of the logon page</li>
      <li><b>prompt.username</b> - A "Username:" prompt string</li>
      <li><b>prompt.password</b> - A "Password:" prompt string</li>
      <li><b>button.submit</b> - "Submit" for the button label</li>
      <li><b>button.reset</b> - "Reset" for the button label</li>
      </ul>
      When the user logs on, the application can store a <code>Locale</code>
      object in the user's session.  This <code>Locale</code> will be used
      to select messages in the appropriate language.  This makes it easy to
      implement giving the user an option to switch languages -- simply change
      the stored <code>Locale</code> object, and all messages are switched
      automatically.</li>
  <li>The <a href="tags.html#errors">errors</a> tag displays any error
      messages that have been stored by a business logic component, or nothing
      if no errors have been stored.  This tag will be described further
      below.</li>
  <li>The <a href="tags.html#form">form</a> tag renders an HTML
      <code>&lt;form&gt;</code> element, based on the specified attributes.
      It also associates all of the fields within this form with a session
      scoped FormBean that is stored under the key <code>logonForm</code>.
      This bean is used to provide initial values for all of the input
      fields that have names matching the property names of the bean.
      If an appropriate bean is not found, a new one will be created
      automatically, using the specified Java class name.</li>
  <li>The <a href="tags:html#text">text</a> tag renders an HTML
      <code>&lt;input&gt;</code> element of type "text".  In this case,
      the number of character positions to occupy on the browser's screen
      has been specified as well.  When this page is executed, the current
      value of the <code>username</code> property of the corresponding bean
      (that is, the value returned by <code>getUsername()</code>).
  <li>The <a href="tags.html#password">password</a> tag is used similarly.
      The difference is that the browser will echo asterisk characters,
      instead of the input value, as the user types their password.</li>.
  <li>The <a href="tags.html#submit">submit</a> and
      <a href="tags.html#reset">reset</a> tags generate the corresponding
      buttons at the bottom of the form.  The text labels for each button
      are created using <a href="tags.html#message">message</a> tags,
      as with the prompts, so that these values are internationalized.</li>
  </ul>
  
  <h4>3.3.3 Input Field Types Supported</h4>
  
  <p>Struts defines tags for all of the following types of input fields,
  with hyperlinks to the corresponding reference information.</p>
  <ul>
  <li><a href="tags.html#checkbox">checkboxes</a></li>
  <li><a href="tags.html#hidden">hidden</a> fields</li>
  <li><a href="tags.html#password">password</a> input fields</li>
  <li><a href="tags.html#radio">radio</a> buttons</li>
  <li><a href="tags.html#reset">reset</a> buttons</li>
  <li><a href="tags.html#select">select</a> lists with embedded</li>
      <a href="tags.html#option">options</a></li>
  <li><a href="tags.html#submit">submit</a> buttons</li>
  <li><a href="tags.html#text">text</a> input fields</li>
  <li><a href="tags.html#textarea">textareas</a></li>
  </ul>
  <p>In every
  case, a field tag must be nested within a <code>form</code> tag, so that
  the field knows what bean to use for initializing displayed values.
  </p>
  
  <h4>3.3.4 Other Useful Presentation Tags</h4>
  
  <p>There are several other tags in the Struts library that are useful in
  creating user interfaces:</p>
  <ul>
  <li><a href="tags.html#enumerate">enumerate</a> repeats its tag body once
      for each element of a specified collection (which can be an Enumeration,
      a Hashtable, a Vector, or an array of objects).</li>
  <li><a href="tags.html#getProperty">getProperty</a> retrieves the specified
      property from the specified bean, and exposes it as a page scope
      bean to the rest of this page.  Among other things, this is a convenient
      way to access a collection to be used by <code>enumerate</code>.</li>
  <li><a href="tags.html#ifParameterEquals">ifParameterEquals</a> evaluates
      its tag body only if a specified request parameter has a specified
      value.</li>
  <li><a href="tags.html#ifParameterNotEquals">ifParameterNotEquals</a>
      evaluates its tag body only if a specified request parameter does not
      have a specified value.</li>
  <li><a href="tags.html#link">link</a> generates a hyperlink, and automatically
      applies URL encoding to maintain session state in the absence of
      cookie support.</li>
  <li><a href="tags.html#parameter">parameter</a> renders the specified
      request parameter's value, suitably filtered for characters that are
      sensitive in HTML.</li>
  <li><a href="tags.html#property">property</a> displays the named bean
      property within a form -- use it instead of <code>text</code> for
      properties that should be read only.</li>
  </ul>
  
  
  <h3>3.4 Other Presentation Techniques</h3>
  
  <p>Although the look and feel of your application can be completely constructed
  based on the standard capabilities of JSP and the Struts custom tag library,
  you should consider employing other techniques that will improve component
  reuse, reduce maintenance efforts, and/or reduce errors.  Several options
  are discussed in the following sections.</p>
  
  
  <h4>3.4.1 Application-Specific Custom Tags</h4>
  
  <p>Beyond using the custom tags provided by the Struts library, it is easy
  to create tags that are specific to the application you are building, to
  assist in creating the user interface.  The example application included with
  Struts illustrates this principle by creating the following tags unique to
  the implementation of this application:</p>
  <ul>
  <li><code>checkLogon</code> - Checks for the existence of a particular session
      object, and forwards control to the logon page if it is missing.  This is
      used to catch cases where a user has bookmarked a page in the middle of
      your application and tries to bypass logging on, or if the user's session
      has been timed out.</li>
  <li><code>linkSubscription</code> - Generates a hyperlink to a details page
      for a Subscription, which passes the required primary key values as
      request attributes.  This is used when listing the subscriptions associated
      with a user, and providing links to edit or delete them.</li>
  <li><code>linkUser</code> - Generates a hyperlink to a details page
      for a User, which passes the required primary key values as
      request attributes.</li>
  </ul>
  
  <p>The source code for these tags is in the <code>src/example</code> directory,
  in package <code>org.apache.struts.example</code>, along with the other Java
  classes that are used in this application.</p>
  
  
  <h4>3.4.2 Page Composition With Includes</h4>
  
  <p>Creating the entire presentation of a page in one JSP file (with custom
  tags and beans to access the required dynamic data) is a very common design
  approach, and was employed in the example application included with Struts.
  However, many applications require the display of multiple logically distinct
  portions of your application together on a single page.</p>
  
  <p>For example, a portal application might have some or all of the following
  functional capabilities available on the portal's "home" page:</p>
  <ul>
  <li>Access to a search engine for this portal.</li>
  <li>One or more "news feed" displays, with the topics of interest customized
      from the user's registration profile.</li>
  <li>Access to discussion topics related to this portal.</li>
  <li>A "mail waiting" indicator if your portal provides free email
      accounts.</li>
  </ul>
  
  <p>The development of the various segments of this site is easier if you
  can divide up the work, and assign different developers to the different
  segments.  Then, you can use the <i>include</i> capability of JavaServer Pages
  technology to combine the results into a single result page.  There are two
  types of <i>include</i> available, depending on when you want the combination
  of output to occur:</p>
  <ul>
  <li>The include <i>directive</i> (<code>&lt;%@ include file="xxxxx"
      %&gt;</code>) is processed when the JSP page is compiled.  It is
      useful when you are including HTML code that will not need to change
      at request time.  It treats the text being included as static text,
      much like the <code>#include</code> directive in C or C++.</li>
  <li>The include <i>action</i> (<code>&lt;jsp:include page="xxxxx"
      flush="true" /&gt;</code>) is processed at request time, and is handled
      transparently by the server.  Among other things, that means you
      can conditionally perform the include by nesting it within a tag
      like <a href="tags.html#ifParameterEquals">ifParameterEquals</a>.</li>
  </ul>
  
  
  <h4>3.4.3 Image Rendering Components</h4>
  
  <p>Some applications require dynamically generated images, like the price
  charts on a stock reporting site.  Two different approaches are commonly used
  to meet these requirements:</p>
  <ul>
  <li>Render a hyperlink with a URL that executes a servlet request.  The
      servlet will use a graphics library to render the graphical image,
      set the content type appropriately (such as to <code>image/gif</code>),
      and send back the bytes of that image to the browser, which will display
      them just as if it had received a static file.</li>
  <li>Render the HTML code necessary to download a Java applet that creates
      the required graph.  You can configure the graph by setting appropriate
      initialization parameters for the applet in the rendered code, or you
      can have the applet make its own connection to the server to receive
      these parameters.</li>
  </ul>
  
  
  <h2>4. Building the Model Components</h2>
  
  
  <h3>4.1 Overview</h3>
  
  <p>The application requirements document that you produced above will likely
  have focused on the user interface to be created.  However, you should ensure
  that the processing required for each submitted request is also clearly
  defined.  In general, the developer of the model components will be focusing
  on the creation of Action Classes (i.e. classes that implement the
  <code>Action</code> interface), supporting JavaBeans components of various
  types, and deciding how to maintain the state of the application persistently
  when the application is not currently operating.  The Action Classes are
  actually part of the Controller in a Model-View-Controller architecture, so
  they are discussed in a subsequent section.</p>
  
  
  <h3>4.2 JavaBeans Components</h3>
  
  <p>The precise nature of the JavaBeans classes required by a particular
  application will vary widely based on its particular requirements.  However,
  the following general categories of beans are often necessary.</p>
  
  
  <h4>4.2.1 ActionForm Beans</h4>
  
  <p>The Struts framework generally assumes that you have created an ActionForm
  bean (that is, a Java class implementing the <code>ActionForm</code> interface)
  for each input form required in your application.  If you define such beans
  in your <code>ActionMapping</code> configuration file (see below), the Struts
  controller servlet will automatically perform the following services for you,
  before calling the appropriate Action Class method:</p>
  <ul>
  <li>Check in the user's session for an instance of a bean of the
      appropriate type, under the appropriate key.</li>
  <li>If there is no such session scope bean available, a new one is
      automatically created and added to the user's session.</li>
  <li>For every request parameter whose name corresponds to the name
      of a property in the bean, the corresponding setter method will
      be called.  This operates in a manner similar to the standard
      JSP action <code>&lt;jsp:setProperty&gt;</code> when you use the
      asterisk wildcard to select all properties.</li>
  <li>The updated <code>ActionForm</code> bean will be passed to the
      Action Class <code>perform()</code> method when it is called,
      making these values immediately available.</li>
  </ul>
  
  <p>When you code your <code>ActionForm</code> beans, keep the following
  principles in mind:</p>
  <ul>
  <li>Generally, there will be very little validation logic in an
      <code>ActionForm</code> bean itself.  This is because the purpose
      of an <code>ActionForm</code> bean is to maintain the most recent
      state of what the user actually typed (whether it is correct or not)
      so that, in the case of detected errors, the same page can be
      redisplayed exactly as the user last entered it.  Then, the user
      need only correct the fields that have errors, rather than typing
      everything over again.  (Remember, the <code>form</code> custom tag
      and the associated field tags do the redisplay part for you.)</li>
  <li>Define a property (with associated <code>getXxx()</code> and
      <code>setXxx()</code>) methods for each field.  The field name
      and property name must match according to the usual JavaBeans
      conventions.  For example, an input field named <code>username</code>
      will cause the <code>setUsername()</code> method to be called.</li>
  <li>When defining String-valued properties, you might want to take special
      actions if a null value is passed to a property setter method.
      In the example application, attempts to set a String property to
      null are changed to set a zero-length String instead.  Note that
      the custom tags for fields, such as <code>text</code>, deal with
      null values correctly by treating them as zero-length strings,
      but such conversions might be useful if you access the properties
      of these beans in other ways.</li>
  </ul>
  
  <p>You should note that a "form", in the sense discussed here, does not
  necessarily correspond to a single JSP page in the user interface.  It is
  common in many applications to have a "form" (from the user's perspective)
  that extends over multiple pages.  Think, for example, of the wizard style
  user interface that is commonly used when installing new applications.  Struts
  encourages you to define a single <code>ActionForm</code> bean that contains
  properties for all of the fields, no matter which page the field is actually
  displayed on.  Likewise, the various pages of the same form should all be
  submitted to the same Action Class.  If you follow these suggestions, the
  page designer can rearrange the fields among the various pages, with no
  changes required to the processing logic in most cases.</p>
  
  
  <h4>4.2.2 Business Logic Beans</h4>
  
  <p>You should model the basic functional logic of your application as a set
  of calls to property setters of JavaBeans, followed by calls to an appropriate
  method to invoke the requested logic.  For maximum code re-use, these beans
  should <b>not</b> know that they are being executed by a servlet.
  If you find yourself having to import a <code>javax.servlet.*</code> class
  in your bean, you know that you're tying yourself to servlets -- this should
  be avoided.</p>
  
  <p>Depending on the complexity and scope of your application, business logic
  beans might be ordinary JavaBeans that interact with a database through JDBC
  calls, or a directory server through JNDI calls.  For larger applications,
  these beans will often be stateful or stateless Session Enterprise JavaBeans
  instead.</p>
  
  
  <h3>4.3 Persistent Storage Options</h3>
  
  <p>Many web applications will utilize a relational database (accessed through
  a JDBC driver) to store the persistent data associated with the application.
  Others will use Entity Enterprise JavaBeans for this purpose, which delegates
  the decisions for how to maintain persistent state to the EJBs themselves.
  If you are using Enterprise JavaBeans for this purpose, follow the client
  design patterns described in the Enterprise JavaBeans specification.</p>
  
  <p>For web applications based on direct database access, a common design
  problem is how to make an appropriate JDBC Connection object available when
  access to the underlying database is required.  There are several possible
  approaches to this problem -- the following rules describe one model for
  dealing with this issue:</p>
  <ul>
  <li>Create or acquire a ConnectionPool class, which lets a set of database
      connections be shared among multiple users.  Struts does not (currently)
      include such a class.</li>
  <li>When the application is initialized, define a servlet with a load on
      startup value in the application deployment descriptor.  Call this the
      "startup" servlet.  (In most cases, there will be no need for any
      requests to be processed directly by this servelt, so there would be
      no <code>&lt;servlet-mapping&gt;</code> element pointing at it.)</li>
  <li>In the <code>init()</code> method of the startup servlet, configure and
      instantiate an instance of your ConnectionPool class, and store it as
      a servlet context attribute (which is the same as an application scope
      bean from the JSP perspective).  It is usually convenient to configure
      the connection pool based on initialization parameters passed to the
      startup servlet.</li>
  <li>In the <code>destroy()</code> method of the startup servlet, include
      logic to gracefully release the connections that have been opened by
      the connection pool.  This will get called when the servlet container
      shuts down this application.</li>
  <li>When an Action Class needs to call a method of a business logic bean
      that requires a database connection (such as "insert a new customer"),
      it will perform steps like this:
      <ul>
      <li>Acquire the connection pool object from the servlet context
          attributes.</li>
      <li>Call the <code>open()</code> method of the connection pool object
          to give you a connection for use within this Action Class call.</li>
      <li>Call the appropriate method of your business logic bean, passing the
          database connection object to be used as an argument.</li>
      <li>Call the <code>close()</code> method of the allocated connection,
          which will cause this connection to be returned to the pool for
          later re-use on some other request.</li>
      </ul>
  <li>A common programming error is to forget to return the connection to the
      pool, which can ultimately lead to running out of connections.  Be sure
      that your Action Class logic always returns the connection, even if the
      business logic bean throws an exception.</li>
  </ul>
  
  <p>Following the design pattern recommended above means that you can design
  your business logic classes without having to worry about how they acquire a
  JDBC Connection to use -- simply include a Connection argument in any method
  call that needs to access the database.  When your business logic class is
  utilized within a web application, it will be the responsibility of the Action
  Class to allocate and release an appropriate connection.  When you use the
  same business logic class, for example, in a batch job, it will be
  the responsibility of that application to provide an appropriate connection
  (which will not need to be acquired from a pool, because most batch jobs
  run in a single-threaded environment).</p>
  
  
  <h2>5. Building the Controller Components</h2>
  
  
  <h3>5.1 Overview</h3>
  
  <p>Now that you have the View and Model components of your application, it is
  time to focus on the Controller components.  Struts includes a servlet
  that implements the primary function of mapping a request URI to an Action
  Class.  Therefore, the primary development responsibilities related to the
  Controller are:</p>
  <ul>
  <li>Write an Action class (that is, an implementation of the
      <code>Action</code> interface) for each logical request
      that may be received.</li>
  <li>Write an ActionMapping class (that is, an implementation of the
      <code>ActionMapping</code> interface) that defines the class
      names and other information associated with each possible
      mapping.</li>
  <li>Write the action mapping configuration file (in XML) that is used
      to configure the controller servlet.</li>
  <li>Update the web application deployment descriptor file (in XML)
      for your application to include the necessary Struts components.</li>
  <li>Add the appropriate Struts components to your application.</li>
  </ul>
  
  
  <h3>5.2 Action Classes</h3>
  
  <p>The <code>Action</code> interface defines a single method that must be
  implemented by the Action Class, as follows:</p>
  <pre>
      public void perform(ActionServlet servlet,
                          ActionMapping mapping,
                          ActionForm form,
                          HttpServletRequest request,
                          HttpServletResponse response)
        throws IOException, ServletException;
  </pre>
  
  <p>The goal of the Action Class is to process this request, and generate the
  corresponding response (or forward control to another component, such as a
  JSP page, that will do this), just as if it were the <code>doGet()</code> or
  <code>doPost()</code> method of a servlet itself.  In the <i>Model 2</i>
  design pattern, a typical Action Class will look like this:
  <ul>
  <li>Validate the current state of the user's session (for example, checking
      that the user has successfully logged on).  If the Action Class finds
      that no logon exists, the request should be forwarded to the JSP page
      that displays the username and password prompts for logging on.</li>
  <li>Validate the request parameters included with this request.  If the
      Action Class finds a problem, it stores appropriate error messages in
      a request scope bean, and forwards control back to the originating
      JSP page so that the errors can be corrected.</li>
  <li>Perform the processing required to deal with this request (such as
      saving a row into a database).  This can be done by code embedded within
      the Action Class itself, or by calling appropriate methods of beans
      being manipulated by the Action Class.</li>
  <li>Update the server-side objects that will be used to create the next
      page of the user interface (typically request scope or session scope
      beans, depending on how long you need to keep these items available).</li>
  <li>Forward this request (using <code>RequestDispatcher.forward()</code> to
      the appropriate JSP page to create the next page of the user interface,
      based on the newly updated beans.</li>
  </ul>
  
  <p>One design issue to remember as you code Action Classes is that they are
  used in a multi-threaded environment.  Two users who make a request to the same
  Action Class at the same time will be sharing the same instance.  So, an
  important design rule is to not use instance variables within the Action
  Class itself.  This helps, because local variables (those created within the
  <code>perform()</code> method), are not shared -- the JVM maintains a stack
  for each active thread.</p>
  
  <p>In addition, you want to guard against Action Classes that are too large.
  This can happen when you embed your business logic in the Action Class itself,
  rather than embedding it in beans that are accessed by the Action Class.  It
  is useful to think of Action Classes as implementing the "Adapter" pattern
  in Design Patterns terminology:</p>
  <ul>
  <li>The Action Class knows it is accessed in a web application environment,
      because it receives arguments defined by the Java Servlet API (such as
      <code>HttpServletRequest</code> and <code>HttpServletResponse</code>.</li>
  <li>The primary behavior of the Action Class should be to "adapt" these
      servlet specific components into general JavaBeans components that do
      not necessarily know they are being executed in a web application.
      This is typically done by calling property setter methods on the beans,
      and then invoking business logic methods as required.</li>
  <li>In simple cases, the business logic itself is embedded within the Action
      Classes.  However, this makes maintenance and re-use of such code more
      difficult.  Try to limit the code in your Action Classes to translating
      the servlet-specific request parameters into generic JavaBeans properties,
      and managing the control flow (such as choosing which JSP page to forward
      to, based on the state of the computation).</li>
  </ul>
  
  <p>The example application included with Struts stretches this design principle
  somewhat, because the business logic itself is embedded in the Action Classes.
  The reason for this is that the focus of the application is on illustrating the
  various features of Struts.  In a "real" version of this application, the logic
  to maintain user subscriptions, for example, would be performed inside
  JavaBeans that talk to a relational database or a directory server, or via
  Enterprise JavaBeans.</p>
  
  
  <h3>5.2 The ActionMapping Implementation</h3>
  
  <p>In order to operate successfully, the Struts controller servlet needs to
  know several things about how each request URI should be mapped to an
  appropriate <code>Action</code> class (along with other related information).
  The required knowledge has been encapsulated in a Java interface named
  <code>ActionMapping</code>, which has the following properties:</p>
  <ul>
  <li><b>actionClass</b> - The fully qualified Java class name of the
      <code>Action</code> class used for this mapping.  The first time
      a particular mapping is used, an instance of this class will be
      created and saved for reuse later.</li>
  <li><b>formAttribute</b> - The name of the session scope bean under which
      the current <code>ActionForm</code> for this mapping is stored.  If
      this property is not defined, no <code>ActionForm</code> will be used.</li>
  <li><b>formClass</b> - The fully qualified Java class name of the
      <code>ActionForm</code> class used for this mapping.  If you are
      using the support for form beans, an instance of this class will be
      created and saved automatically whenever necessary.</li>
  <li><b>path</b> - The request URI path that is matched to select this
      mapping.  See below for examples of how matching works.</li>
  </ul>
  
  <p>Struts includes a convenient implementation of the
  <code>ActionMapping</code> interface, in a class named
  <code>org.apache.struts.action.ActionMappingBase</code>.  If you do not need
  to define any additional properties for your own mappings, feel free to use
  this class as your <code>ActionMapping</code> class, as described in the
  following section.  However, it is also possible to define an
  <code>ActionMapping</code> implementation (perhaps extending the
  <code>ActionMappingBase</code> class) that contains additional properties.
  The controller servlet knows how to configure these custom properties
  automatically, because it uses the Struts Digester module to read the
  configuration file.</p>
  
  <p>In the example application included with Struts, this feature is used to
  define two additional properties:</p>
  <ul>
  <li><b>failure</b> - The context-relative URI to which control should be
      forwarded if the Action class detects some sort of problem with the
      input fields it received.  This will typically be the name of the
      JSP page from which the request was sent, which will cause the form
      to be redisplayed (with the error messages set by the Action Class
      and the most recent input values from the ActionForm bean).</li>
  <li><b>success</b> - The context-relative URI to which control should be
      forwarded if the Action class successfully performs the required
      function.  This will typically be the name of a JSP page that prepares
      the next page of the conversation flow for this application.</li>
  </ul>
  
  <p>Using these two extra properties, the Action classes in the example
  application are almost totally independent of the actual names of the JSP
  pages that are used by the page designers.  The pages can be renamed (for
  example) during a redesign, with negligible impact on the Action classes
  themselves.  If the names of the "next" JSP pages were hard coded into the
  Action classes, they would also need to be modified.</p>
  
  
  <h3>5.3 The Action Mappings Configuration File</h3>
  
  <p>How does the controller servlet learn about the mappings you want?  It
  would be possible (but tedious) to write a small Java class that simply
  instantiated new <code>ActionMapping</code> instances, and called all of
  the appropriate setter methods.  To make this process easier, Struts includes
  a Digester module that is capable of reading an XML-based description of
  the desired mappings, creating the appropriate objects along the way.</p>
  
  <p>The developer's responsibility is to create an XML file named
  <code>action.xml</code>, and place it in the WEB-INF directory of your
  application.  (Note that no DTD for this file is required, because the
  actual attributes used can be different for different users.)  The
  outermost XML element must be <code>&lt;action-mapping&gt;</code>, and
  within this element are nested zero or more <code>&lt;action&gt;</code>
  elements -- one per mapping that you wish to define.</p>
  
  <p>The <code>action.xml</code> file from the example application includes
  the following mapping entry for the "log on" function, which we will use
  to illustrate the requirements:</p>
  <pre>
    &lt;action-mapping&gt;
  
      &lt;action   path="/logon"
         actionClass="org.apache.struts.example.LogonAction"
       formAttribute="logonForm"
           formClass="org.apache.struts.example.LogonForm"
             success="/mainMenu.jsp"
             failure="/logon.jsp"
      /&gt;
  
    &lt;/action-mapping&gt;
  </pre>
  
  <p>As you can see, this mapping matches the path <code>/logon</code> (actually,
  because the example application uses extension mapping, the request URI you
  specify in a JSP page would end in <code>/logon.do</code>).  When a request
  that matches this path is received, an instance of the <code>LogonAction</code>
  class will be created (the first time only) and used.  The controller servlet
  will look for a session scoped bean under key <code>logonForm</code>, creating
  and saving a bean of the specified class if needed.  The <code>success</code>
  and <code>failure</code> properties indicate that the logon action should
  forward control to the main menu if successful, or back to the logon form
  if not successful (such as an invalid username or password).</p>
  
  
  <h3>5.4 The Application Deployment Descriptor</h3>
  
  <p>The final step in setting up the application is to configure the application
  deployment descriptor (stored in file <code>WEB-INF/web.xml</code>) to include
  all the Struts components that are required.  Using the deployment descriptor
  for the example application as a guide, we see that the following entries need
  to be created or modified.</p>
  
  
  <h4>5.4.1 Configure the Action Servlet Instance</h4>
  
  <p>Add an entry defining the action servlet itself, along with the appropriate
  initialization parameters.  Such an entry might look like this:
  <pre>
      &lt;servlet&gt;
        &lt;servlet-name&gt;action&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;
        &lt;init-param&gt;
          &lt;param-name&gt;application&lt;/param-name&gt;
          &lt;param-value&gt;org.apache.struts.example.ApplicationResources&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;init-param&gt;
          &lt;param-name&gt;config&lt;/param-name&gt;
          &lt;param-value&gt;/WEB-INF/action.xml&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;init-param&gt;
          &lt;param-name&gt;debug&lt;/param-name&gt;
          &lt;param-value&gt;2&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;init-param&gt;
          &lt;param-name&gt;mapping&lt;/param-name&gt;
          &lt;param-value&gt;org.apache.struts.example.ApplicationMapping&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
      &lt;/servlet&gt;
  </pre>
  
  <p>The initialization parameters supported by the controller servlet are
  described in the <a href="api/index.html">Javadocs</a> for the
  <code>ActionServlet</code> class, under the description for the
  <code>init()</code> method.</p>
  
  
  <h4>5.4.2 Configure the Action Servlet Mapping</h4>
  
  <p>There are two common approaches to defining the URLs that will
  be processed by the controller servlet -- prefix matching and extension
  matching.  An appropriate mapping entry for each approach will be
  described below.</p>
  
  <p>Prefix matching means that you want all URLs that start (after the context
  path part) with a particular value to be passed to this servlet.  Such an
  entry might look like this:</p>
  <pre>
      &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;action&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/execute/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  </pre>
  <p>which means that a request URI to match the <code>/logon</code> path
  described earlier might look like this:
  <pre>
      http://www.mycompany.com/myapplication/execute/logon
  </pre>
  <p>where <code>/myapplication</code> is the context path under which your
  application is deployed.</p>
  
  <p>Extension mapping, on the other hand, matches request URIs to the action
  servlet based on the fact that the URI ends with a period followed by a
  defined set of characters.  For example, the JSP processing servlet is mapped
  to the <code>*.jsp</code> pattern so that it is called to process every
  JSP page that is requested.  To use the <code>*.do</code> extension (which
  implies "do something"), the mapping entry would look like this:
  <pre>
      &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;action&lt;/servlet-name&gt;
        &lt;url-pattern&gt;*.do&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  </pre>
  <p>and a request URI to match the <code>/logon</code> path described
  earlier might look like this:
  <pre>
      http://www.mycompany.com/myapplication/logon.do
  </pre>
  
  
  <h4>5.4.3 Configure the Struts Tag Library</h4>
  
  <p>Next, you must add an entry defining the Struts tag library.  The entry
  should look like this:
  <pre>
    &lt;taglib&gt;
      &lt;taglib-uri&gt;/WEB-INF/struts.tld&lt;/taglib-uri&gt;
      &lt;taglib-location&gt;/WEB-INF/struts.tld&lt;/taglib-location&gt;
    &lt;/taglib&gt;
  </pre>
  
  <p>which tells the JSP system where to find the tag library descriptor
  for this library (in your application's WEB-INF directory, instead of
  out on the Internet somewhere).</p>
  
  
  <h4>5.4.4 Add Struts Components To Your Application</h4>
  
  <p>To use Struts when your application executes, you must copy the
  <code>struts.tld</code> file to your <code>WEB-INF</code> directory,
  and the <code>struts.jar</code> file to your <code>WEB-INF/lib</code>
  directory.</p>
  
  </body>
  </html>